Payflow payment integration in ruby on rails - ruby-on-rails

I'm using paypal for payment and here is main function and parameters which are used for payment.
def self.paypal_url(.....)
values = {
:business => 'email#id.com',
:cmd => '_cart',
:upload => 1,
:return => return_url,
:invoice => "#{customer.id}_#{sType.id}_#{Time.now}",
:notify_url => notify_url
}
values.merge!({
"amount_1" => amount,
"item_name_1" => sType.show_title,
"discount_amount_1" => discount
# "quantity_1" => '1'
})
"https://www.paypal.com/cgi-bin/webscr?" + values.to_query
end
But now i want to use PayFlow. Kindly guide me which parameter i have to change and what will be the final url as for payment is "https://www.paypal.com/cgi-bin/webscr?" + values.to_query.
Kindly guide me?

There is a Rails example of payflow pro with hosted pages on git:
https://gist.github.com/supairish/5872581
The code gets the token to use in an iframe in your view.
You can see an example here:
https://developer.paypal.com/docs/classic/payflow/gs_ppa_hosted_pages/
I also found this resource helpful:
How do I test my integration with the Payflow Gateway using the hosted pages?
www.paypal-knowledge.com/infocenter/index?page=content&widgetview=true&id=FAQ1493

Related

recurring paypal with preapproval adaptive payment

I have create rails application and implemented preapproval payment using adaptivepayments-sdk-ruby gem. I plan to use this as recurring payment.
this is my code for create preapproval:
ADAPTIVE_PAYMENT.build_preapproval({
:cancelUrl => my_cancel_url,
:currencyCode => "USD",
:paymentPeriod => "DAILY",
:returnUrl => my_return_url,
:startingDate => DateTime.now.in_time_zone
})
and then I use this code to charge:
ADAPTIVE_PAYMENT.build_pay({
:actionType => "PAY",
:cancelUrl => my_cancel_url,
:currencyCode => "USD",
:feesPayer => "PRIMARYRECEIVER",
:preapprovalKey => Preapproval_key,
:receiverList => {
:receiver => [{
:amount => 100,
:email => example#example.com,
:primary => true},
{
:amount => $100,
:email => example#example.com,
:primary => false }
]
},
:returnUrl => my_return_url
})
How to make it automatically charged every day without execute the pay code again?
Im pretty sure there is no automatic pay feature from paypals side. I know that you can setup how many monthly / weekly payments they are signing up for but I think thats just for the pre-approval agreement.
However, why dont you just setup a CRON job and let it take care of it for you? I was super nervous about doing this with paypal adaptive payments the first time but its actually saved me SO much time and its a lot more reliable than any human could be with its ability to send job reports after its done.

ActiveMerchant's support for determining the account status (verified/unverified) of a PayPal Express Checkout customer/buyer

I am currently working on a Ruby-on-Rails web-application that accepts PayPal payments through PayPal's Express Checkout and ActiveMerchant. I have done several research on ActiveMerchant's support for determining if a customer/buyer has paid using either a verified or unverified PayPal account but I got no luck on finding a helpful guide.
I find it also that ActiveMerchant is currently not well-documented so it's not that helpful at all.
Below are the relevant codes that my project is currently using. On PaymentsController#purchase, I temporarily used the #params['protection_eligibility'] and the #params['protection_eligibility_type'] methods of the ActiveMerchant::Billing::PaypalExpressResponse object that is returned by the EXPRESS_GATEWAY.purchase method call, to assess if a PayPal customer/buyer has a verified/unverified PayPal account. Later I found out that this is not a reliable basis for knowing the customer's account status.
I hope somebody can give me a wisdom on knowing whether a PayPal customer/buyer has a verified/unverified account using Ruby-on-Rails' ActiveMerchant or using other alternatives on Rails.
# config/environments/development.rb
config.after_initialize do
ActiveMerchant::Billing::Base.mode = :test
paypal_options = {
# credentials removed for this StackOverflow question
:login => "",
:password => "",
:signature => ""
}
::EXPRESS_GATEWAY = ActiveMerchant::Billing::PaypalExpressGateway.new(paypal_options)
end
# app/models/payment.rb
class Payment < ActiveRecord::Base
# ...
PAYPAL_CREDIT_TO_PRICE = {
# prices in cents(US)
1 => 75_00,
4 => 200_00,
12 => 550_00
}
STATUSES = ["pending", "complete", "failed"]
TYPES = ["paypal", "paypal-verified", "paypal-unverified", "wiretransfer", "creditcard"]
# ...
end
# app/controllers/payments_controller.rb
class PaymentsController < ApplicationController
# ...
def checkout
session[:credits_qty] = params[:credit_qty].to_i
total_as_cents = Payment::PAYPAL_CREDIT_TO_PRICE[session[:credits_qty]]
setup_purchase_params = {
:allow_guest_checkout => true,
:ip => request.remote_ip,
:return_url => url_for(:action => 'purchase', :only_path => false),
:cancel_return_url => url_for(:controller => 'payments', :action => 'new', :only_path => false),
:items => [{
:name => pluralize(session[:credits_qty], "Credit"),
:number => 1,
:quantity => 1,
:amount => Payment::PAYPAL_CREDIT_TO_PRICE[session[:credits_qty]]
}]
}
setup_response = EXPRESS_GATEWAY.setup_purchase(total_as_cents, setup_purchase_params)
redirect_to EXPRESS_GATEWAY.redirect_url_for(setup_response.token)
end
def purchase
if params[:token].nil? or params[:PayerID].nil?
redirect_to new_payment_url, :notice => I18n.t('flash.payment.paypal.error')
return
end
total_as_cents = Payment::PAYPAL_CREDIT_TO_PRICE[session[:credits_qty]]
purchase_params = {
:ip => request.remote_ip,
:token => params[:token],
:payer_id => params[:PayerID],
:items => [{
:name => pluralize(session[:credits_qty], "Credit"),
:number => 1,
:quantity => 1,
:amount => Payment::PAYPAL_CREDIT_TO_PRICE[session[:credits_qty]]
}]
}
purchase = EXPRESS_GATEWAY.purchase total_as_cents, purchase_params
if purchase.success?
payment = current_user.payments.new
payment.paypal_params = params
payment.credits = session[:credits_qty]
payment.amount = Payment::PAYPAL_CREDIT_TO_PRICE[session[:credits_qty]]
payment.currency = "USD"
payment.status = "complete"
if(purchase.params["receipt_id"] && (purchase.params["success_page_redirect_requested"] == "true"))
payment.payment_type = "creditcard"
else
if purchase.params['protection_eligibility'] == 'Eligible' && purchase.params['protection_eligibility_type'] == 'ItemNotReceivedEligible,UnauthorizedPaymentEligible'
payment.payment_type = 'paypal-verified'
else
payment.payment_type = 'paypal-unverified'
end
end
payment.ip_address = request.remote_ip.to_s
payment.save!
SiteMailer.paypal_payment(payment).deliver
SiteMailer.notice_payment(payment).deliver
notice = I18n.t('flash.payment.status.thanks')
redirect_to profile_url, :notice => notice
else
notice = I18n.t('flash.payment.status.failed', :message => purchase.message)
redirect_to new_payment_url, :notice => notice
end
end
# ...
end
I used PayPal's paypal-sdk-merchant gem to do the job ActiveMerchant wasn't able to help me with (getting the status of a payer's account: verified/unverified PayPal account. I followed the installation of paypal-sdk-merchant on https://github.com/paypal/merchant-sdk-ruby
gem 'paypal-sdk-merchant'
bundle install
rails generate paypal:sdk:install
Then I set-up their samples https://github.com/paypal/merchant-sdk-ruby#samples. After setting-up the samples, go to /samples of your Rails app and you will find a lot of code generator for what ever function you need from PayPal's API. Don't forget to configure your config/paypal.yml. I configured the username, password and signature (can be obtained from your PayPal sandbox specifically your test seller account) and removed the app_id in my case.
I obtained the following code for getting a PayPal payer's account status (verified/unverified) using PayPal's samples (/samples) and placed it on a class method of a model in my app:
def self.get_paypal_payer_status(transaction_id)
require 'paypal-sdk-merchant'
api = PayPal::SDK::Merchant::API.new
get_transaction_details = api.build_get_transaction_details({
:Version => "94.0",
:TransactionID => transaction_id
})
get_transaction_details_response = api.get_transaction_details(get_transaction_details)
get_transaction_details_response.payment_transaction_details.payer_info.payer_status
end
I'm not familiar with ActiveMerchant so I can't tell you specific to that, but with any Express Checkout implementation you can use GetExpressCheckoutDetails to obtain the payers information which will include a PAYERSTATUS parameter with a value of "verified" or "unverified".
It's an optional call, but I would assume ActiveMerchant is probably including it so you just need to track that down and pull that parameter accordingly.
Alternatively, you can use Instant Payment Notification (IPN) to receive transaction information and you will get back a payer_status parameter here as well.

preapproved payments with paypal in rails 3.2

I send this info to paypal for using preapproved payment feature:
response = gateway.preapprove_payment(
:return_url => user_orders_url(current_user),
:cancel_url => user_orders_url(current_user),
:requestEnvelope => {"errorLanguage" => "en_US"},
:start_date => Time.now,
:end_date => Time.now + (60*60*24) * 30,
:currency_code =>"USD",
:senderEmail =>"email address of sender",
:max_amount => "20.00",
:maxNumberOfPayments => "1",
:notify_url => ipn_notification_user_orders_url(current_user),
)
redirect_to (gateway.redirect_url_for(response["preapprovalKey"]))
p response
I get a message in paypal page:
This transaction is invalid. Please return to the recipient's website and try again.
I am using the method build_preapproval_payment from this gem https://github.com/jpablobr/active_paypal_adaptive_payment/blob/master/lib/active_merchant/billing/gateways/paypal_adaptive_payment.rb
This is the output in my log console:
#<ActiveMerchant::Billing::AdaptivePaymentResponse:0xb7c6838 #json="{\"responseEnvelope\":{\"timestamp\":\"2012-07-23T09:32:42.631-07:00\",\"ack\":\"Success\",\"correlationId\":\"0c4df4aefe651\",\"build\":\"DEV\"},\"preapprovalKey\":\"PA-8D4362235H161382C\"}", #response=#<Hashie::Rash preapproval_key="PA-8D4362235H161382C" response_envelope=#<Hashie::Rash ack="Success" build="DEV" correlation_id="0c4df4aefe651" timestamp="2012-07-23T09:32:42.631-07:00">>, #xml_request="<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<PreapprovalRequest>\n <requestEnvelope>\n <detailLevel>ReturnAll</detailLevel>\n <errorLanguage>en_US</errorLanguage>\n <senderEmail>sender_email</senderEmail>\n </requestEnvelope>\n <endingDate>2012-08-22T18:32:40</endingDate>\n <startingDate>2012-07-23T18:32:40</startingDate>\n <maxTotalAmountOfAllPayments>20.00</maxTotalAmountOfAllPayments>\n <maxNumberOfPayments>1</maxNumberOfPayments>\n <currencyCode>USD</currencyCode>\n <cancelUrl>http://localhost:3000/en/u/maserranocaceres/orders</cancelUrl>\n <returnUrl>http://localhost:3000/en/u/maserranocaceres/orders</returnUrl>\n <ipnNotificationUrl>http://localhost:3000/en/u/maserranocaceres/orders/ipn_notification</ipnNotificationUrl>\n</PreapprovalRequest>\n", #request={"PreapprovalRequest"=>{"requestEnvelope"=>{"detailLevel"=>"ReturnAll", "errorLanguage"=>"en_US", "senderEmail"=>"microf_1342709287_biz#gmail.com"}, "endingDate"=>"2012-08-22T18:32:40", "startingDate"=>"2012-07-23T18:32:40", "maxTotalAmountOfAllPayments"=>"20.00", "maxNumberOfPayments"=>"1", "currencyCode"=>"USD", "cancelUrl"=>"http://localhost:3000/en/u/maserranocaceres/orders", "returnUrl"=>"http://localhost:3000/en/u/maserranocaceres/orders", "ipnNotificationUrl"=>"http://localhost:3000/en/u/maserranocaceres/orders/ipn_notification"}}, #action="Preapproval">
Where have I the error?
Thank you!
Well, according to my investigation of the source code of that gem the proper redirect_url method for preapproved payments is redirect_pre_approval_url_for
redirect_pre_approval_url_for(token)

Ruby add_item for eBay

I am attempting to write a ruby on rails app that posts an item to eBay. Cody Fauser/Garry Tan have a gem called ebayApi which is built on top of the ebay gem. When I attempt to post an item, I am getting an error back from ebay that says the condition ID is required for this category. I have found a category that does not require the condition, and I can post to that category. Searching through the eBay API documentation, I have found a tag conditionID under the "item" class. However, in the documentation for ebayAPI, there is no such tag. Looking back at the ebay API documentation, there is an older way to specify condition, using lookup_attributes. I have noted that the return xml is coming in API version 745, and Garry Gan's updated of the ruby interface is running version 609. I have tried using the lookup, and seem to get the same error (condition required). I am using the following code to specify the item:
#ebay = Ebay::Api.new :auth_token => #seller.ebay_token
item = Ebay::Types::Item.new( :primary_category => Ebay::Types::Category.new(:category_id => #ebayTemplate.categoryID),
:title => #ebayTemplate.name,
:description => #ebayTemplate.description,
:location => #ebayTemplate.location,
:start_price => Money.new((#ebayTemplate.startPrice*100).to_d, #ebayTemplate.currency),
:quantity => 1,
:listing_duration => #ebayTemplate.listingDuration,
:country => #ebayTemplate.country,
:currency => #ebayTemplate.currency,
:payment_methods => ['VisaMC', 'PayPal'],
:paypal_email_address => '********#gmail.com',
:dispatch_time_max => 3,
:lookup_attributes => [Ebay::Types::LookupAttribute.new( :name => "Condition", :value => "New")],
# :attribute_sets => [
# Ebay::Types::AttributeSet.new(
# :attribute_set_id => 2919,
# :attributes => [
# Ebay::Types::Attribute.new(
# :attribute_id => 10244,
# :values => [ Ebay::Types::Val.new(:value_id => 10425) ]
# )
# ]
# )
# ],
:shipping_details => Ebay::Types::ShippingDetails.new(
:shipping_service_options => [
# ShippingServiceOptions.new(
# :shipping_service_priority => 2, # Display priority in the listing
# :shipping_service => 'UPSNextDay',
# :shipping_service_cost => Money.new(1000, 'USD'),
# :shipping_surcharge => Money.new(299, 'USD')
# ),
Ebay::Types::ShippingServiceOptions.new(
:shipping_service_priority => 1, # Display priority in the listing
:shipping_service => #ebayTemplate.shipSvc,
:shipping_service_cost => Money.new((#ebayTemplate.shipSvcCost*100).to_d, #ebayTemplate.currency),
:shipping_surcharge => Money.new((#ebayTemplate.shipSurcharge*100).to_d, #ebayTemplate.currency)
)
],
:international_shipping_service_options => [
Ebay::Types::InternationalShippingServiceOptions.new(
:shipping_service => 'USPSPriorityMailInternational',
:shipping_service_cost => Money.new((#ebayTemplate.shipSvcCost*100).to_d, #ebayTemplate.currency),
:shipping_service_priority => 2,
:ship_to_location => #ebayTemplate.shipToLocation
)
]
),
:return_policy => Ebay::Types::ReturnPolicy.new (
:description => 'this product for suckers only!',
:returns_accepted_option => 'ReturnsAccepted'
)
#:condition_id => 1000
)
#response = #ebay.add_item(:item => item)
As you can see, it is just a mutation of the example given by Cody Fauser. The condition_id at the bottom will bring up an error as there is no such attribute. It seems to me there is no facility for this in the gem since the requirement came into existence after the gem was created. I have not been able to find any other gems to connect with ebay. I have also noticed, there are very little complaints about this even though people are still downloading the gem (10 people downloaded it today). I think there are quite a number of people writing for ebay. Is there a key word I am missing to specify the condition? A work around that people have been using? Another gem I have missed?
There is an existing item_conditions_codes.rb in the gem's type directory and only has two values New and Used. Guess you could add more values in there. However still needs mapping to ID's per the updating (and changed from Attributes) method
You have to modify in the gem library in .. ruby/1.8/gems/ebayapi-0.12.0/lib/ebay/types/item.rb
and add the following new lines
# added to allow ConditionID to be pushed into XML
numeric_node :condition_id, 'ConditionID', :optional => true
then in your ruby ebay code use the following convention
:condition_id => 1500,
At least that seems to work for me right now.

Pre-filling first and last name in Paypal setExpressCheckout using ActiveMerchant

I'm trying to get Paypal SetExpressCheckout operation to add first and last name for billing. I'm using ActiveMerchant. I'm seeing the address field pre-populated (street, state, city,zip-code) but nothing else.
#### gateway ######
gateway = ActiveMerchant::Billing::PaypalExpressGateway.new(:login => 'login',:password => 'pass',:signature => 'sig')
### options ######
#options = Hash.new
#options.merge!(:ip => '127.0.0.1')
#options.merge!(:return_url => '127.0.0.1')
#options.merge!(:return_url => 'http://www.google.com')
#options.merge!(:cancel_return_url => 'http://www.google.com')
#options.merge!(:name => 'name')
#options.merge!(:description => 'description')
#options.merge!(:max_amount => 5000)
#options.merge!(:solution_type => 'Sole')
#options.merge!(:no_shipping => 1)
#options.merge!(:address_override => 1)
### build address
#address = Hash.new
#address.merge!(:name => "Joe User")
#address.merge!(:address1 => "111 ABCD EFG")
#address.merge!(:address2 => nil)
#address.merge!(:city => "Fremont")
#address.merge!(:state => "CA")
#address.merge!(:country => "US")
#address.merge!(:phone => "408-111-2222")
#options.merge!(:address => #address)
setup_response = gateway.setup_purchase(5000, #options)
redirect_to gateway.redirect_url_for(setup_response.token)
On the resultant page, I'm not seeing the name pre-filled for billing.
What am I doing wrong?
Thanks
I had the same issue as you did. After some research I came to the conclusion that this is a bug in ActiveMerchant. Please see the issue that I filed. It includes an explanation of how I patched my code to make phone number and names work:
https://github.com/Shopify/active_merchant/issues/161

Resources