No such customer: cus_************ (Stripe::InvalidRequestError) when customer exists - ruby-on-rails

I am working on an E-Commerce market place called foodsy. I am using stripe connect for the purpose. Connected accounts are created using stripe-connect-omniauth. And foodsy has several customers. An order for an Sku is created in rails controller by
Stripe.api_key = "sk_test_************"
Stripe::Order.create(
{:currency => 'usd',
:items => [
{
:type => 'sku',
:parent => "sku_************"
}
] },
{ :stripe_account => "acct_************" }
)
It creates an order with id or_************ .
The customer who exist on the foodsy platform buys it ,
order=Stripe::Order.retrieve("or_************",stripe_account: "acct_************")
order.pay(customer: "cus_************")
But this code returns an error No such customer: cus_************ (Stripe::InvalidRequestError).
The customer exist as I can see him on dashboard and source attribute is set on stripe. So why is it going wrong ?

The problem is that the customer exists on the platform's account, but not on the connected account you're trying to create the charge on.
You need to share the customer from the platform account to the connected account:
# Create a token from the customer on the platform account
token = Stripe::Token.create(
{:customer => "cus_7QLGXg0dkUYWmK"},
{:stripe_account => "acct_17BTxDCioT3wKMvR"}
)
# Retrieve the order on the connected account and pay it using the token
order = Stripe::Order.retrieve("or_17BUNHCioT3wKMvREWdDBagG",
stripe_account: "acct_17BTxDCioT3wKMvR"
)
order.pay(source: token.id)

This can also happen if you use the wrong APiKey

Related

Stripe Payment Error: Must provide source or customer

I've been trying to implement a payment method for a shopping cart using card information attached to the user via a subscription model. And while the latter works fine, whenever I attempt to create a charge for the cart, I get the "Must provide source or error."
Here's some code to get started. Let me know if you need more.
checkouts_controller.rb
def create
customer = Stripe::Customer.create(
source: params[:stripeToken],
email: 'paying.user#example.com',
)
charge = Stripe::Charge.create(
amount: current_cart.total,
currency: 'usd',
description: "Order ##{current_cart.id}"
)
end
Error logs from Stripe Post Body
{
"amount": "9500",
"currency": "usd",
"description": "Order #1"
}
And from the response body
{
"error": {
"code": "parameter_missing",
"doc_url": "https://stripe.com/docs/error-codes/parameter- missing",
"message": "Must provide source or customer.",
"type": "invalid_request_error"
}
}
I’m using the standard 4242 4242 4242 4242 card that is actually recorded and attached to my user via my subscription model. Card info like the brand, last four digits, expiration month and year all appear in my view when I go to add a different card. The stripe_id is also present when I check in the console.
I have checked stripe documentation and copied the snippet from their create action from https://stripe.com/docs/checkout/rails but this only trigged the error “Cannot charge a customer with no active card” despite the fact that this card is currently being used for a subscription.
So where did I goof at?
You need to make sure that the customer you create is passed in on the charge create call:
charge = Stripe::Charge.create(
customer: customer,
amount: current_cart.total,
currency: 'usd',
description: "Order ##{current_cart.id}"
)
Or you can use the source directly as:
charge = Stripe::Charge.create(
source: params[:stripeToken],
amount: current_cart.total,
currency: 'usd',
description: "Order ##{current_cart.id}"
)
Both options and examples can be found here
moving from comment to an answer
Hi #Grasshopper27, looks like the customer you created is not being created with the source. You should look into Dashboard -> Logs to look at the request body for the /customer creation request and see if the token is being passed in.
I would also like to note that this Rails doc is a bit outdated, you should try out updated Checkout to really simplify your integration: stripe.com/docs/payments/checkout

Stripe API Invalid Request: Must provide source or customer

I'm working on the Stripe API and building a custom checkout function - My error is specifically telling me I must provide a source or customer. This is my controller for creating charges:
I thought I was successfully creating a source and/or customer with the following code (I also included the post logs on my stripe dashboard)
Stripe::Charge.create(
:amount => #amount,
:currency => 'usd',
:source => params[:stripeToken],
)
Stripe::Customer.create(
:email => params[:stripeEmail],
:source => params[:stripeToken]
)
"error": {
"code": "parameter_missing",
"doc_url": "https://stripe.com/docs/error-codes/parameter-missing",
"message": "Must provide source or customer.",
"type": "invalid_request_error"
}
}
I did go through the docs but I guess I'm still a little lost
Thanks for any assistance!
Update: here is the return of my API POST requests.
Update2: I see that a customer is being created when I send a charge.
Update 3: Source property is set to the stripeToken parameter, representing the payment method provided. The token is automatically created by Checkout. - this seems possibly connected to my issue - maybe it's not correctly posting?
So it did turn out to be a token request - since I was using a test card for test purposes I imagine I had to pass a test token to ensure that the test card would work.
I believe the Rails Params I was using (: source => params[:stripeToken]
) are fine for production but not when checking against given cards. In case someone comes across this as I did (and of course this probably isn't the first time it was asked on SO)
When using the Stripe API you see there is a token tab beside the test card numbers - I assumed those were optional or "for something else" for some reason. THEY ARE NOT.
You'll want to make sure the token matches whatever test card you plan on using (I think)
My Stripe controller now looks like this
Stripe::Charge.create({
:amount => #amount,
:currency => 'usd',
:source => 'tok_visa', #params[:stripeToken] might be for in production I think this is for testing.,
:description => 'Your Donation to Victoria University',
:statement_descriptor => 'Victoria University'
# it seems test tokens must be set as string.
})
Decided to leave my comments in there - because why not?
P.S You'll need different token types for different card payment types. If you switch cards - switch tokens as well !!!! - the tokens are tabbed beside the test card numbers.

How to create plans if they don't exist

I want to create subscription plans in stripe programatically, and I want to be able to run this many times so if the plans exist it should just ignore it.
I noticed if I try and retrieve a plan it throws an exception if it doesn't exist:
plan1 = Strie::Plan.retrieve("abcd123")
>>Stripe::InvalidRequestError: No such plan: abcd123
I create a plan using:
Stripe::Plan.create(.....)
I have a plans model that has all my plans, so I ideally want to do this:
Plan.all.each do |plan|
# create stripe plan here if it doesn't exist
end
What is the best way to handle this exception if the plan exists in stripe already?
Take a look at https://stripe.com/docs/api#error_handling
If you attempt to create a plan with an id that already exists, the request will fail and Stripe will throw an invalid request error. You should be able to wrap your plan creation call to account for errors. A barebones example:
require "stripe"
Stripe.api_key = "sk_test_xxxyyyzzz"
MyPlans.each do |plan|
# try to create a plan
begin
my_plan = Stripe::Plan.create(
:amount => plan.amount,
:interval => "month",
:name => plan.name,
:currency => "usd",
:id => plan.id
)
puts my_plan
# catch any invalid request errors
rescue Stripe::InvalidRequestError => e
puts e.json_body[:error]
end
end

Rails - Stripe::InvalidRequestError (Must provide source or customer.)

I'm building an application (based in online resource). You can sign up or login with devise. Then, you can buy a product. Or make your own list and sell your products.
I'm integrating Stripe. When I create the Charge, I get this error in the console: Stripe::InvalidRequestError (Must provide source or customer.).
Here is the code of the orders_controller.rb for the charge action:
Stripe.api_key = ENV["STRIPE_API_KEY"]
token = params[:stripeToken]
begin
charge = Stripe::Charge.create(
:amount => (#listing.price * 100).floor,
:currency => "usd",
:card => token
)
flash[:notice] = "Thanks for ordering!"
rescue Stripe::CardError => e
flash[:danger] = e.message
end
Of course I'm taking a look in the Stripe API Documentation here: Charge documentation example and here: Charge full API Reference
I'm not sure how to handle the :resource or customer. I saw in other materials in the web that some people create a customer. In other sites it says that the :card is deprecated, so I'm a little confused.
I will leave the github repository of my project, and feel free to take a look. I'm trying to deal with Transfers and Recipients too. Project Repository
Thanks.
As mentioned in the docs, stripe expects either customer or source to be mentioned while creating a charge. So, you either need to
Create a customer on stripe(if you want to charge that customer in future too) from the token you received, and mention that customer while creating a charge,
customer = Stripe::Customer.create(source: params[:stripeToken])
charge = Stripe::Charge.create({
:amount => 400,
:currency => "usd",
:customer => customer.id,
:description => "Charge for test#example.com"
})
Or, if you don't want to create a customer, then directly mention received token as a source,
Stripe::Charge.create({
:amount => 400,
:currency => "usd",
:source => params[:stripeToken],
:description => "Charge for test#example.com"
})
For anyone going through the Stripe docs, you may have something like this (using an existing account)
account_links = Stripe::AccountLink.create({
account: 'acct_1032D82eZvKYlo2C',
refresh_url: 'https://example.com/reauth',
return_url: 'https://example.com/return',
type: 'account_onboarding',
})
if so, just change it to look like this (i.e. include the actual account.id you created in the previous step):
account_links = Stripe::AccountLink.create({
account: account.id,
refresh_url: 'https://example.com/reauth',
return_url: 'https://example.com/return',
type: 'account_onboarding',
})

How do I insert X-PAYPAL headers with Rails Invoice SDK?

I'm using the paypal SDK for invoicing located here:
https://github.com/paypal/invoice-sdk-ruby
This works great.
I integrated the paypal permissions SDK for rails:
https://github.com/paypal/permissions-sdk-ruby
The authorization workflow is working great.
So now I need to put them together. The documentation for the permissions sdk leaves off after you get your token. It doesn't explain how to use it with the other paypal SDKs (at least not so I could understand :D ) The invoice sdk tells you to see the Auth sdk.
Paypal tells me:
# Third-party Auth headers
-H "X-PAYPAL-SECURITY-SUBJECT:<receiverEdress>" # Merchant's PayPal e-mail
-H "X-PAYPAL-AUTHENTICATION:<OAuthSig>" # Generated OAuth Signature
Don't know how to insert that. The request is generated here in my model:
#create_and_send_invoice = api.build_create_and_send_invoice(paypalized || default_api_value)
The data itself is assembled in the invoice model like so:
paypalized = {
:access_token => self.user.paypal_token,
:invoice => {
:merchantEmail => self.user.paypal_email || self.user.email,
:payerEmail => self.client.email,
:itemList => #itemlist,
:currencyCode => "USD",
:paymentTerms => "DueOnReceipt",
:invoiceDate => self.updated_at,
:number => self.name,
:note => self.description,
:merchantInfo => #businessinfo
# project / Invoice title?
} # end invoice
} # end paypalized
return paypalized
This implementation is not working and the access_token field is being rejected. I looked through the gems associated with the sdks but can't see where the headers themselves are built or how to interact with that.
UPDATE: Found this which gives me a clue...
INVOICE_HTTP_HEADER = { "X-PAYPAL-REQUEST-SOURCE" => "invoice-ruby-sdk-#{VERSION}" }
This seems to be used here during calls in the paypal-sdk-invoice gem:
# Service Call: CreateAndSendInvoice
# #param CreateAndSendInvoiceRequest
# #return CreateAndSendInvoiceResponse
def CreateAndSendInvoice(options = {} , http_header = {})
request_object = BuildCreateAndSendInvoice(options)
request_hash = request_object.to_hash
...
I notice that there's two arguments: options and http_header. It's possible I can modify the http_header argument and pass it this way in my controller:
#create_and_send_invoice_response = api.create_and_send_invoice(#create_and_send_invoice, #cutsom_header)
or maybe
#create_and_send_invoice = api.build_create_and_send_invoice(data, custom_header)
I'll keep this updated since I googled around a lot and couldn't find any clear answers on how to do this...
You have to pass the token and token_secret while creating API object for third-party authentication.
#api = PayPal::SDK::Invoice::API.new({
:token => "replace with token",
:token_secret => "replace with token-secret" })

Resources