Update stripe subscription payment card details rails - ruby-on-rails

I am Using ruby 2.4.0p0 (2016-12-24 revision 57164) [x86_64-linux],Rails 5.2.4.4 and Using stripe 5.26.0
I have created stripe subscription
customer = if current_user.stripe_customer_id?
Stripe::Customer.retrieve(current_user.stripe_customer_id)
else
Stripe::Customer.create({
:email => current_user.email,
:source => params[:stripeToken],
:description => "Tukaweb Stripe Subscriptions customer= #{current_user.email}"
},
{
api_key: Rails.configuration.stripe[:secret_key]
}
)
end
## check if user have already took the subscription
if current_user.subscriptions.where(payment_status: 'paid', software_package_id: #subscription.software_package_id).empty?
## with trail period
subscription = Stripe::Subscription.create({
customer: customer,
items: [
{price: 'price_1HVF68E9ijv19IzXdDVmKN5e'},
],
trial_end: (Time.now + 1.month).to_i,
})
else
## without trail period
subscription = Stripe::Subscription.create({
customer: customer,
items: [
{price: 'price_1HVF68E9ijv19IzXdDVmKN5e'},
],
})
end
current_user.update({
stripe_customer_id: customer.id
})
Now I want to update stripe subscriptions card details it giving error:
customer = Stripe::Customer.retrieve(current_user.stripe_customer_id)
stripe_subscription = SoftwareUser.find(params[:software_user_id])
subscription = customer.subscriptions.retrieve(stripe_subscription.stripe_subscription_id)
subscription.source = params[:stripeToken]
subscription.save
Error as:
Stripe::InvalidRequestError (Received unknown parameter: source):
can you please suggest how to update the card details for a subscription.

This is failing because there is no source attribute on a Subscription.
In this particular case, you're relying on the fact that when the Subscription is created, that it will fall back to using the default source of the Customer to fund the Subscription [1] because there is no default payment method. If you want to change the Source that pays the Subscription, you would have to change the default source of the Customer [2].
All that being said, the recommendation today is not to use Sources at all but rather to create a PaymentMethod [3] using Stripe.js and Elements. You attach this PaymentMethod to the Customer [4] Then you would set this payment method as default on either the Invoice [5], Subscription [6] or Customer [7].
The steps are outlined in more detail here [8].
[1] https://stripe.com/docs/api/subscriptions/create?lang=ruby#create_subscription-default_payment_method
[2] https://stripe.com/docs/api/customers/object?lang=ruby#customer_object-default_source
[3] https://stripe.com/docs/js/payment_intents/confirm_card_payment
[4] https://stripe.com/docs/api/payment_methods/attach?lang=ruby
[5] https://stripe.com/docs/api/invoices/object?lang=ruby#invoice_object-default_payment_method
[6] https://stripe.com/docs/api/subscriptions/object?lang=ruby#subscription_object-default_payment_method
[7] https://stripe.com/docs/api/customers/object?lang=ruby#customer_object-invoice_settings-default_payment_method
[8] https://stripe.com/docs/billing/subscriptions/fixed-price#create-subscription

Related

Stripe API in Rails

I'm trying to use source_transaction with the Rails API so that I can have managed accounts that create payments and are later sent to other accounts.
I'm getting the error Stripe::InvalidRequestError: Insufficient funds in Stripe account. In test mode, you can add funds to your available bal
ance (bypassing your pending balance) by creating a charge with 4000 0000 0000 0077 as the card number. You can use th
e the /v1/balance endpoint to view your Stripe balance (for more details, see stripe.com/docs/api#balance).
But usinrg source_transaction I thought was supposed to bypass using my balance and only transfer funds once the transaction cleared.
Here is the code I'm using
charge = Stripe::Charge.create(
:customer => stripe_cust_id,
:amount => total_amount_owed,
:description => 'Groundwork Subscription Charge',
:currency => 'usd',
:transfer_group => invoice_number
)
...
transfer = Stripe::Transfer.create({
:amount => amount_to_transfer,
:currency => "usd",
:destination => StripeInfo.where(account_id: project_owner.accounts.first.id).first.stripe_id,
:application_fee => (amount_to_transfer*0.05).round,
:source_transaction => charge[:charge_id]
# :transfer_group => invoice_number
})

Stripe Payment Works on LocalHost but Does not work on Heroku

Hope all is good
I am baffled by why my stripe payment in ruby on rails works on my localhost which is c9.io account but when I deployed my code in Heroku, it gives me this error:
Cannot charge a customer that has no active card
my orders.coffee file:
jQuery ->
Stripe.setPublishableKey($('meta[name="stripe-key"]').attr('content'))
payment.setupForm()
payment =
setupForm: ->
$('#new_order').submit ->
$('input[type=submit]').attr('disabled', true)
obj = Stripe.card.createToken($('#new_order'), payment.handleStripeResponse)
alert(JSON.stringify(obj));
handleStripeResponse: (status, response) ->
if status == 200
$('#new_order').append($('<input type="hidden" name="stripeToken" />').val(response.id))
$('#new_order')[0].submit()
else
$('#stripe_error').text(response.error.message).show()
$('input[type=submit]').attr('disabled', false)
out come of my orders.coffee in localhost:
my application.html.erb header section
<head>
<title>Estydemo</title>
<%= stylesheet_link_tag 'application', media: 'all'%>
<%= javascript_include_tag 'https://js.stripe.com/v2/', type: 'text/javascript' %>
<%= javascript_include_tag 'application' %>
<%= csrf_meta_tags %>
<%= tag :meta, :name=> 'stripe-key', :content => STRIPE_PUBLIC_KEY %>
</head>
my orders_controller.rb stripe section:
Stripe.api_key = ENV["stripe_api_key"]
#flash[:notice] = Stripe.api_key
#puts "stripe api key is " + Stripe.api_key
token = params[:stripeToken]
begin
customer = Stripe::Customer.create(
:source => token,
:description => "Customer.create"
)
charge = Stripe::Charge.create(
:amount => (#listing.price * 100).floor,
:description => 'charge.create',
:currency => "usd",
:customer => customer.id
)
flash[:notice] = "Thanks for ordering!"
rescue Stripe::CardError => e
flash[:danger] = e.message
end
my application.js
// This is a manifest file that'll be compiled into application.js, which will include all the files
// listed below.
//
// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
// or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path.
//
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
// compiled file.
//
// Read Sprockets README (https://github.com/sstephenson/sprockets#sprockets-directives) for details
// about supported directives.
//
//= require jquery
//= require jquery_ujs
//= require bootstrap
//= require_tree .
my stripe dashboard for a sample where I get from heroku
Could anyone let me know why I have such an odd issue?
left one is from heroku and right one is from localhost
If there is more info needed, please ask it away.
So this error means that the charge creation request (Stripe::Charge.create(...)) failed because the customer has no payment source.
This in turn means that when you created the customer:
customer = Stripe::Customer.create(
:source => token,
:description => "Customer.create"
)
token must have been either nil or an empty string, and as a result no source parameter was sent to Stripe. You can check this by looking at the log entry for the customer creation request in your Stripe dashboard.
This in turn means that params[:stripeToken] was itself nil or an empty string.
Unfortunately I'm not sure why that's the case. I'd recommend adding some logs, both in the stripeResponseHandler callback in your CoffeeScript file and in the Rails controller, to check whether the token was created and submitted successfully.
I think when test on Heroku, you create charge with new customer and this customer haven't any card default active. Please add create new card before create charge on orders_controller.rb
Stripe.api_key = ENV["stripe_api_key"]
#flash[:notice] = Stripe.api_key
#puts "stripe api key is " + Stripe.api_key
token = params[:stripeToken]
begin
customer = Stripe::Customer.create(
:source => token,
:description => "Customer.create"
)
card = customer.sources.create({:source => token})
charge = Stripe::Charge.create(
:amount => (#listing.price * 100).floor,
:description => 'charge.create',
:currency => "usd",
:customer => customer.id,
:source => card.id
)
flash[:notice] = "Thanks for ordering!"
rescue Stripe::CardError => e
flash[:danger] = e.message
end
I think your error is simply that you're creating a Stripe customer account and passing the token to the Customer but not passing the token to the actual Charge. This needs to be done in both cases. Many use cases for Stripe can be for creating subscriptions or for processing the payment later which is why the Customer Create will take the token on file. But to create a charge you also need to do this. So I would edit the code to include the token in the Charge create like this:
Edited 11/03
Actually I went ahead and reverted the code back to what you had. From reading through the API some more I think that you may be able to make it work this way just fine. That is if you intend on creating a customer that can be charged again later.The direction I would look then is at the fact that it works locally but not on Heroku. I think this is less about the Stripe code and more about the change to production. Look at the ENV variable and seeing if it's set for both dev and production. But not only that, I would precompile your assets as Heroku tends to have an issue with CSS or jQuery at least for me when I go from dev to production. Run RAILS_ENV=production bundle exec rake assets:precompile and that should do the trick, then push to master.
See: https://devcenter.heroku.com/articles/rails-asset-pipeline
token = params[:stripeToken]
begin
customer = Stripe::Customer.create(
:source => token,
:description => "Customer.create"
)
charge = Stripe::Charge.create(
:amount => (#listing.price * 100).floor,
:description => 'charge.create',
:currency => "usd",
:customer => customer.id
)
flash[:notice] = "Thanks for ordering!"
rescue Stripe::CardError => e
flash[:danger] = e.message
end
If you're just looking to charge them but not retain the information in Stripe you can just use:
token = params[:stripeToken]
begin
charge = Stripe::Charge.create(
:amount => (#listing.price * 100).floor,
:currency => "usd",
:source => token,
:description => "Example charge"
)
flash[:notice] = "Thanks for ordering!"
rescue Stripe::CardError => e
flash[:danger] = e.message
end
Edit 11/07
Ok so in looking through the actual repo, I think that you are having an issue because you don't have the necessary javascript call to create the token in the first place. I would reference the Stripe Api here:
https://stripe.com/docs/stripe.js#collecting-card-details
and insert this into your orders.js file, but that's contingent on the various input fields being named with those classes in the form you use to create the order. I hope this now helps point you in the correct direction. Everything else is looking like it should be good from what I can tell.
Stripe.card.createToken({
number: $('.card-number').val(),
cvc: $('.card-cvc').val(),
exp_month: $('.card-expiry-month').val(),
exp_year: $('.card-expiry-year').val()
}, stripeResponseHandler);

iOS integration with Heroku backend

I have been having a lot of difficulty with this, I just can't see where I am going wrong. Although I am fairly rookie, I am trying to do something a ton of app developers must routinely succeed in doing - process an Apple Pay charge through Stripe's example Sinatra / Ruby backend available at:
https://github.com/stripe/example-ios-backend
I believe I have done everything fine:
My Stripe account is set up, I am in test mode, I have verified my bank, it all looks fine.
I am using Test API keys, secret and publishable : the following is the code in my slightly modified web.ry file: you can see that the app working at least at the ‘/‘ endpoint if you go to: https://ibidurubypay.herokuapp.com - please note I have absolutely NO IDEA what I am doing in Rails - the only mods I have made are:
I have inserted the Stripe test key
I have slightly modified the initial return message to check changes are being updated on Heroku
I changed the currency to GBP (stripe account is GBP)
Code is:
require 'sinatra'
require 'stripe'
require 'dotenv'
require 'json'
Dotenv.load
Stripe.api_key = ENV['sk_test_mystripetestkeymystripetestkey']
get '/' do
status 200
return "Great, terrific, your backend is set up. Now you can configure the Stripe example iOS apps to point here."
end
post '/charge' do
# Get the credit card details submitted by the form
source = params[:source] || params[:stripe_token] || params[:stripeToken]
customer = params[:customer]
# Create the charge on Stripe's servers - this will charge the user's card
begin
charge = Stripe::Charge.create(
:amount => params[:amount], # this number should be in cents
:currency => "gbp",
:customer => customer,
:source => source,
:description => "Example Charge"
)
rescue Stripe::StripeError => e
status 402
return "Error creating charge: #{e.message}"
end
status 200
return "Charge successfully created"
end
get '/customers/:customer/cards' do
customer = params[:customer]
begin
# Retrieves the customer's cards
customer = Stripe::Customer.retrieve(customer)
rescue Stripe::StripeError => e
status 402
return "Error retrieving cards: #{e.message}"
end
status 200
content_type :json
cards = customer.sources.all(:object => "card")
selected_card = cards.find {|c| c.id == customer.default_source}
return { :cards => cards.data, selected_card: selected_card }.to_json
end
post '/customers/:customer/sources' do
source = params[:source]
customer = params[:customer]
# Adds the token to the customer's sources
begin
customer = Stripe::Customer.retrieve(customer)
customer.sources.create({:source => source})
rescue Stripe::StripeError => e
status 402
return "Error adding token to customer: #{e.message}"
end
status 200
return "Successfully added source."
end
post '/customers/:customer/select_source' do
source = params[:source]
customer = params[:customer]
# Sets the customer's default source
begin
customer = Stripe::Customer.retrieve(customer)
customer.default_source = source
customer.save
rescue Stripe::StripeError => e
status 402
return "Error selecting default source: #{e.message}"
end
status 200
return "Successfully selected default source."
end
delete '/customers/:customer/cards/:card' do
card = params[:card]
customer = params[:customer]
# Deletes the source from the customer
begin
customer = Stripe::Customer.retrieve(customer)
customer.sources.retrieve(card).delete()
rescue Stripe::StripeError => e
status 402
return "Error deleting card"
end
status 200
return "Successfully deleted card."
end
As you can see the Ruby web app is running fine…
Switching to Xcode, I then go and download Stripe's example apps at: https://github.com/stripe/stripe-ios/tree/master/Example
I open ‘Stripe.xcworkspace’ in the ‘stripe-ios-master’ folder.
In my Apple Developer account, I go set up a new app ‘com.AH.thenameigaveit’ Merchant
I ticked ApplePay and then set up a Merchant Identifier with: merchant.com.AH.thenameigaveit
I go to Stripe and create a CSR certificate which I then link up with my Merchant ID in Apple Dev.
I got my new Apple CER file and uploaded it to Stripe - and I was able to verify that it was successfully installed.
Back in Xcode I hit Fix Issue for provisioning profile problem and it all gets accepted.
My entitlements file says ‘com.apple.developer.in-app-payments’
Now in Xcode I go to ViewController.swift in Stripe's 'Simple' example and change the values of the various user variables as follows:
stripePublishableKey = “'pk_test_mystripetestkeymystripetestkey'” my test publishable key
backendChargeURLString = “https://ibidurubypay.herokuapp.com”
appleMerchantId = “merchant.com.AH.thenameigaveit”
Note the Stripe 'Simple' example Swift code refers to currency as USD whereas my web.ry script refers to “gbp”, however from what I can tell in the past when I tried it a couple of times each way, that looks as if it shouldn’t matter as the currency value is not passed to the Ruby script (and my Stripe account is in GBP.)
So, time to build and run to an iPhone 6 plus with Apple Pay activated on it with a live Visa credit card… app builds successfully first time..
First time around it says :”Payment request is invalid: check your entitlements”, so I go to Capabilities and make sure the correct Merchant ID is checked against ApplePay - build again and this time we get further - the Apple Pay screen comes up perfectly on the screen, specifying the Apple Pay linked credit card to pay $10 for the cool shirt.. - I do the touch, it comes up with ‘Processing Payment’ then shortly after ‘Payment Not Completed!’ and the Apple Pay dialog retreats back down the screen taking back to the option to ‘Buy a shirt’
So, I know absolutely nothing about communicating with this server backend except to try and glean some info coming back from the call, so I insert:
print ("data: \(data), \r\r response: \(response), \r\r error: \(error)")
which gives me:
data: Optional(),
response: Optional( { URL:
*(ASBEFORE)*ibidurubypay.herokuapp.com/charge } { status code: 402, headers {
Connection = "keep-alive";
"Content-Length" = 248;
"Content-Type" = "text/html;charset=utf-8";
Date = "Tue, 28 Jun 2016 00:16:43 GMT";
Server = "WEBrick/1.3.1 (Ruby/2.1.2/2014-05-08)";
Via = "1.1 vegur";
"X-Content-Type-Options" = nosniff;
"X-Frame-Options" = SAMEORIGIN;
"X-Xss-Protection" = "1; mode=block"; } }),
error: nil
That appears to be a Card Decline message, but there’s nothing wrong with the card.
On my Stripe account at the portal, a token was successfully created at the time: 2016/06/28 01:16:42
…however, there is no evidence of the 402 decline I can see anywhere here, maybe I am not looking in the right place…
I would be really grateful if anyone could let me know what’s going wrong - I am tearing my hair out, I have been stumped on this on and off for days.
ok, so I had asked the guys from Stripe this question and blow me over they solved it straight off - the issue was:
Stripe.api_key = ENV['sk_test_mystripetestkeymystripetestkey'] in my Ruby script...
EITHER: it should be:
Stripe.api_key = 'sk_test_mystripetestkeymystripetestkey' (note no ENV[])
OR: BETTER: if should be as it was originally downloaded from Stripe, an environment variable, which I then set up in Stripe, so in the script:
Stripe.api_key = ENV['STRIPE_TEST_SECRET_KEY']
then update your Heroku configuration to create an environment variable named STRIPE_TEST_SECRET_KEY with your test API key as the value: https://devcenter.heroku.com/articles/config-vars
Easy as pie once you know how, thank you Stripe for great support!

Paypal adaptive payments for digital goods

I am struggling to figure out how to get Digital goods to work with my adaptive payments. I am using the Paypal ruby gem can someone please show me a code sample for a payments with 2 receivers and for Digital Goods?
I already am approved for micro payments by paypal.
# Build request object
#pay = #api.build_pay({
:actionType => "PAY",
:cancelUrl => "http://localhost:3000/account", #sandbox
:currencyCode => "USD",
#:feesPayer => "SENDER",
:ipnNotificationUrl => "http://596w.localtunnel.com/pay/#{purchased.id}", #sandbox
:memo => "Test payment",
:receiverList => {
:receiver => [{
:amount => price.round(2),
:email => "an email", #sandbox
:paymentType => "DIGITALGOODS",
:primary => true
},
unless account.user.email == "an email"
{
:amount => mycut.round(2),
:email => "anemail", #sandbox
:paymentType => "DIGITALGOODS"
}
end
] },
:returnUrl => "http://localhost:3000/pay/complete/" #sandbox
})
I get the error:
This feature (Digital Goods) is not supported.
As far as i know on the the Express Payment option of Paypal supports digital good. if you can replace your integration to use activemerchant and use the PaypalDigitalGoodsGateway you'd do yourself a favor.
Log a ticket at https://www.paypal.com/mts and they'll enable it for you.
For what it's worth, the product you're trying to use is: Digital Goods for Express Checkout.
Express Checkout itself is available by default on all accounts, but that team can enable Digital Goods on your Sandbox account.
This error may appear if you get the payKey successfully but redirect user to wrong url later.
Here is haml code for form for embedded payments, including Digital Goods.
= javascript_include_tag "//www.paypalobjects.com/js/external/apdg.js"
%form.text-center{:action => ::PAYPAL_ADAPTIVE_GATEWAY.embedded_flow_url, :target => "PPDGFrame"}
%input#type{:name => "expType", :type => "hidden", :value => "light"}
%input#paykey{:name => "payKey", :type => "hidden", :value => #payKey}
%input#submitBtn{:type => "submit", :value => 'Pay with PayPal' }
:javascript
var returnFromPayPal = function(){
//do something on PayPal popup closing here
};
var dgFlowMini = new PAYPAL.apps.DGFlowMini({ trigger: 'submitBtn', callbackFunction: returnFromPayPal});
//works only for lightbox mode
function MyEmbeddedFlow(embeddedFlow) {
this.embeddedPPObj = embeddedFlow;
this.paymentSuccess = function () {
this.embeddedPPObj.closeFlow();
// handle payment success here
window.location.reload(true);
};
this.paymentCanceled = function () {
this.embeddedPPObj.closeFlow();
// handle payment cancellation here
window.location.reload(true);
};
}
var myEmbeddedPaymentFlow = new MyEmbeddedFlow(dgFlowMini);
::PAYPAL_ADAPTIVE_GATEWAY.embedded_flow_url is from activemerchant, you may use 'https://www.sandbox.paypal.com/webapps/adaptivepayment/flow/pay' for sandbox or 'https://www.paypal.com/webapps/adaptivepayment/flow/pay' for production.

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.

Resources