I am receiving this error in my log console:
The amount is invalid
I am working in development env, with http://localhost:3000/
I have in my controller:
def pay
pay_request = PaypalAdaptive::Request.new
data = {
"returnUrl" => user_orders_url(current_user),
"requestEnvelope" => {"errorLanguage" => "en_US"},
"currencyCode" => "USD",
"receiverList" =>
{ "receiver" => [
{"receiver"=> [{"email"=>"email1", "amount"=>"10.00", "primary" => true}, {"email"=>"email2", "amount"=>"9.00", "primary" => false}]}
]},
"cancelUrl" => user_orders_url(current_user),
"actionType" => "PAY",
"ipnNotificationUrl" => ipn_notification_user_orders_url(current_user)
}
pay_response = pay_request.pay(data)
if pay_response.success?
# Send user to paypal
redirect_to pay_response.preapproval_paypal_payment_url
else
puts pay_response.errors.first['message']
redirect_to root_url, alert: "Something went wrong. Please contact support."
end
end
What am I doing bad?
Can you test with
"amount"=>10
Or
"amount"=>"10"
The error was fixed:
The error is in "primary" => true and "primary" => false.
I have removed this code and now the controller does works fine.
Thank you very much!
Related
i am trying to implement braintree payments into a ruby app, and everything seems to be working fine, but when i pass fail_on_duplicate_payment_method_card as an option i am getting invalid keys: options[fail_on_duplicate_payment_method_card]
result = Braintree::PaymentMethod.create(
:customer_id => current_user.customer_cim_id,
:payment_method_nonce => 'fake-valid-amex-nonce',
:cardholder_name => "#{current_user.first_name} #{current_user.last_name}",
:options => {
:make_default => true,
:fail_on_duplicate_payment_method_card => true
}
)
if result.success?
customer = Braintree::Customer.find(current_user.customer_cim_id)
puts customer.id
puts customer.payment_methods[0].token
else
p result.errors
end
Full disclosure: I work at Braintree. If you have any further questions, feel free to contact our support team.
fail_on_duplicate_payment_method_card should be fail_on_duplicate_payment_method.
result = Braintree::PaymentMethod.create(
:customer_id => current_user.customer_cim_id,
:payment_method_nonce => 'fake-valid-amex-nonce',
:cardholder_name => "#{current_user.first_name} #{current_user.last_name}",
:options => {
:make_default => true,
:fail_on_duplicate_payment_method => true
}
)
I am using this gem active_paypa_adaptive_payment for payments system on a web page.
preapproval_payment feature is working fine and I have a preapproval_key inside my database.
Now I want execute the agreement with my preaproval_key.
I have been checking cancel_preapproval method and it does work fine.
I dont need go to paypal page with cancel_preapproval method in my cancel_order method in my order controller.i.e.:
preapproval_key = #order.payment.preapproval_key
response = gateway.cancel_preapproval(:preapproval_key => preapproval_key)
respond_to do |format|
if response.ack == "Success"
#order.update_attributes
format.html { redirect_to user_orders_url(current_user), notice: t(".cancel_order_success") }
else
format.html { redirect_to user_orders_url(current_user), alert: t(".cancel_order_wrong") }
end
end
How can I execute the agreement with my preapproval_key for transfer funds from sender account to receiver account?
is it possible this feature for execute the agreement instead cancel the agreement with my preapproval_key?
Thank you very much
The solution is add the field :preapproval_key to the response. Something like, in your action:
def your_action
recipients = [{:email => 'receiver_email',
:amount => some_amount,
:primary => true},
{:email => 'receiver_email',
:amount => recipient_amount,
:primary => false}
]
response = gateway.setup_purchase(
:return_url => url_for(:action => 'action', :only_path => false),
:cancel_url => url_for(:action => 'action', :only_path => false),
:ipn_notification_url => url_for(:action => 'notify_action', :only_path => false),
:receiver_list => recipients
:preapproval_key => "your_preapproval_key_here",
)
respond_to do |format|
if object.update_attributes
format.html { redirect_to root_path, notice: t(".success") }
else
format.html { redirect_to root_path, alert: t(".wrong") }
end
end
end
Note that you must have preapproval_key available. You can save it to your database when you make preapproved payment or you can get it with the api PreapprovalDetails
With this way you can make a pay with a preapproved payment. I recommend you add fields as :fees_payer, :senderEmail, :memo...etc for more details.
Regards!
I was working on an app in which I need to work with ipn, but it seems it does not work well.
I am trying to get the notification in success action and have specified the correct url in paypal sandbox.
def success
topup = current_user.topups.last
logger.debug "topup -------->"
logger.debug topup.amount.to_i
# raise request
details = EXPRESS_GATEWAY.details_for(topup.express_token)
logger.debug "details ------->"
logger.debug details.payer_id
# raise params[:payer_id]
response = EXPRESS_GATEWAY.purchase(topup.price_in_cents,{
:ip => request.remote_ip,
:token => topup.express_token,
:payer_id => details.payer_id
})
logger.debug "Response starts here --------->"
logger.debug response
if response.success?
amount = topup.amount.to_i
current_user.credits = current_user.credits.to_i + amount
current_user.save!
flash[:success] = "Thank you for the top up"
# #account_history = current_user.account_histories.build
# #account_history.update_attribute(:type => "Top Up", :details => "", :amount => amount, :user_id => current_user.id)
redirect_to current_user
notify = Paypal::Notification.new request.raw_post
logger.info "Notifying --------->"
logger.info notify
logger.info notify.status
logger.info "Notifying 2 --------->"
logger.info notify.acknowledge
logger.debug notify.status
if notify.acknowledge
logger.debug "Notifying --------->"
logger.debug notify.mc_gross
logger.debug notify.txn_id
end
else
redirect_to root_url
end
end
notify.acknowledge does not return anything (it is blank)
After banging my head for quite some time I was able to solve the issue. Posting my solution just in case anyone is stuck in the similar situation :-
One important thing is that IPN sends post data to the IPN listener so make sure you have a route defined for this.
I also had a before_filter :authenticate_user! , because of which I was getting html code 401. Had to skip before filter for notify action.
def pay_with_account
topup = Topup.find(params[:id])
response = EXPRESS_GATEWAY.setup_purchase(topup.price_in_cents,{
:ip => request.remote_ip,
:currency_code => 'GBP',
:return_url => topups_success_url(topup),
:notify_url => topups_notify_url(topup),
:cancel_return_url => topups_cancel_url(topup),
# :allow_guest_checkout => true,
:items => [{:name => "Topup", :quantity => 1,:description => "Top up my account", :amount => topup.price_in_cents}]
})
topup.update_attribute :express_token, response.token
redirect_to EXPRESS_GATEWAY.redirect_url_for(response.token)
end
This is the return url :-
def success
topup = current_user.topups.last
details = EXPRESS_GATEWAY.details_for(topup.express_token)
response = EXPRESS_GATEWAY.purchase(topup.price_in_cents,{
:ip => request.remote_ip,
:currency_code => 'GBP',
:token => topup.express_token,
:payer_id => details.payer_id
})
if response.success?
amount = topup.amount.to_i
current_user.credits = current_user.credits.to_i + amount
current_user.save!
redirect_to user_payments_path(current_user)
flash[:success] = "Your transaction was successfully completed"
else
flash[:error] = "Your transaction could not be compelted"
redirect_to user_payments_path(current_user)
end
end
This is the notify url :-
def notify
notify = Paypal::Notification.new(request.raw_post)
if notify.acknowledge
#account_history = topup.user.account_histories.build
#account_history.update_attributes(:payment_type => "Top up",:status => notify.status, :amount => notify.gross)
if params[:payer_status] == "verified"
#account_history.update_attributes(:details => "Pay Pal #{#account_history.id}")
elsif params[:payer_status] == "unverified"
#account_history.update_attributes(:details => "Credit Card #{#account_history.id}")
end
#account_history.save
end
render :nothing => true
end
routes :-
get "topups/pay_with_account"
get "topups/pay_without_account"
get "topups/success"
get "topups/cancel"
get "topups/notify"
post "topups/notify
I'm trying to create simple PayPal Pay API operation, when I run this code from console it gave me response, that payment is created.
Now, when I'm tring to run it from my controller it gives me
Authentication+failed.+API+credentials+are+incorrect.
Here is my controller :
def pay
require 'httpclient'
require 'xmlsimple'
clnt = HTTPClient.new
credentials = {
'USER' => 'payer_1342623102_biz_api1.gmail.com',
'PWD' => '1342623141',
'SIGNATURE' => 'Ay2zwWYEoiRoHTTVv365EK8U1lNzAESedJw09MPnj0SEIENMKd6jvnKL '
}
header = {"X-PAYPAL-SECURITY-USERID" => "payer_1342623102_biz_api1.gmail.com",
"X-PAYPAL-SECURITY-PASSWORD" => "1342623141",
"X-PAYPAL-SECURITY-SIGNATURE" => "Ay2zwWYEoiRoHTTVv365EK8U1lNzAESedJw09MPnj0SEIENMKd6jvnKL ",
"X-PAYPAL-REQUEST-DATA-FORMAT" => "NV",
"X-PAYPAL-RESPONSE-DATA-FORMAT" => "XML",
"X-PAYPAL-APPLICATION-ID" => "APP-80W284485P519543T"
}
data = {"actionType" => "PAY",
"receiverList.receiver(0).email"=> "denmed_1342605975_biz#gmail.com",
"receiverList.receiver(0).amount" => "10",
"currencyCode" => "USD",
"cancelUrl" => "http://127.0.0.1:3000",
"returnUrl" => "http://127.0.0.1:3000",
"requestEnvelope.errorLanguage" => "en_US"}
uri = "https://svcs.sandbox.paypal.com/AdaptivePayments/Pay"
res = clnt.post(uri, data, header)
#xml = XmlSimple.xml_in(res.content)
payKey = #xml["payKey"].to_s()
payKey = payKey.tr("[]", "")
payKey = payKey[1..20]
redirect_to "https://svcs.sandbox.paypal.com/AdaptivePayments/Pay?cmd=_ap-payment&paykey=#{payKey}"
end
Is everything ok ? Can anyone suggest reason my request fails ?
One good man found my error. I redirect user to the wrong url.
This line:
redirect_to "https://svcs.sandbox.paypal.com/AdaptivePayments/Pay?cmd=_ap-payment&paykey=#{payKey}"
Should be:
redirect_to "https://sandbox.paypal.com/webscr?cmd=_ap-payment&paykey=#{paykey}"
I got the same error: I realized I forgot to include
sandbox_email_address: xxx#example.com
in my yml file
This is my controller:
setup_purchase method does works fine for me with my data api, but preapprove_payment method does not works.
def pay
gateway = ActiveMerchant::Billing::PaypalAdaptivePayment.new(
:login => "email",
:password => "pass",
:signature => "signature",
:appid => "APP-80W284485P519543T" )
response = gateway.preapprove_payment(
:return_url => user_orders_url(current_user),
:cancel_url => user_orders_url(current_user),
:sender_email =>"email",
:start_date => Time.now,
:end_date => Time.now,
:currency_code =>"USD",
:max_amount => "20",
:maxNumberOfPayments => "2")
puts response.preapproval_key
puts gateway.debug
# for redirecting the customer to the actual paypal site to finish the payment.
redirect_to (gateway.redirect_url_for(response["preapproval_key"]))
end
I get in log:
PA-8K9332086D720151L
{:url=>#<URI::HTTPS:0xdf9bd18 URL:https://svcs.sandbox.paypal.com/AdaptivePayments/Preapproval>, :request=>"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<PreapprovalRequest>\n <requestEnvelope>\n <detailLevel>ReturnAll</detailLevel>\n <errorLanguage>en_US</errorLanguage>\n <senderEmail>email</senderEmail>\n </requestEnvelope>\n <endingDate>2012-07-20T19:09:20</endingDate>\n <startingDate>2012-07-20T19:09:20</startingDate>\n <maxTotalAmountOfAllPayments>20</maxTotalAmountOfAllPayments>\n <maxNumberOfPayments>2</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</PreapprovalRequest>\n", :response=>"{\"responseEnvelope\":{\"timestamp\":\"2012-07-20T10:09:22.459-07:00\",\"ack\":\"Success\",\"correlationId\":\"ada6a3e7da93d\",\"build\":\"DEV\"},\"preapprovalKey\":\"PA-8K9332086D720151L\"}"}
Full response:
#<ActiveMerchant::Billing::AdaptivePaymentResponse:0xc817278 #json="{\"responseEnvelope\":{\"timestamp\":\"2012-07-23T07:43:56.603-07:00\",\"ack\":\"Success\",\"correlationId\":\"7f759c5da73ad\",\"build\":\"DEV\"},\"preapprovalKey\":\"PA-1M101813XU7801314\"}", #response=#<Hashie::Rash preapproval_key="PA-1M101813XU7801314" response_envelope=#<Hashie::Rash ack="Success" build="DEV" correlation_id="7f759c5da73ad" timestamp="2012-07-23T07:43:56.603-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>microf_1342709161_per#gmail.com</senderEmail>\n </requestEnvelope>\n <endingDate>2012-08-22T16:43:54</endingDate>\n <startingDate>2012-07-23T16:43:54</startingDate>\n <maxTotalAmountOfAllPayments>20</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</PreapprovalRequest>\n", #request={"PreapprovalRequest"=>{"requestEnvelope"=>{"detailLevel"=>"ReturnAll", "errorLanguage"=>"en_US", "senderEmail"=>"email"}, "endingDate"=>"2012-08-22T16:43:54", "startingDate"=>"2012-07-23T16:43:54", "maxTotalAmountOfAllPayments"=>"20", "maxNumberOfPayments"=>"1", "currencyCode"=>"USD", "cancelUrl"=>"http://localhost:3000/en/u/maserranocaceres/orders", "returnUrl"=>"http://localhost:3000/en/u/maserranocaceres/orders"}}, #action="Preapproval">
What am I doing wrong?
The problem was fixed.
Change
gateway.redirect_url_for(response["preapprovalKey"])
to
gateway.redirect_pre_approval_url_for(response["preapprovalKey"])
The correct method is redirect_pre_approval_url_for
You can see the fix in this post:
preapproved payments with paypal in rails 3.2
Thank you very much!