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
I'm trying to check the user entered cvc code. I have stored stripe customer_id and the stripe card_id. I want to verify the CVC code before charging the user.
Below are code for creating charge.
charge = Stripe::Charge.create(
:amount => 1000,
:currency => "usd",
:customer => "cus_3sAc**************",
:card => "card_18m*********************",
:description => "Testing multiple card payment",
:capture => false # default true,
:cvc => 125
)
But cvc parameter is invalid here. If I remove the cvc, it works fine. But it won't check the CVC verification. How can I check this?
You cannot provide the CVC directly in a charge creation request. (Incidentally, if you did provide the CVC directly in the charge creation request sent by your backend server, that would mean your backend server has access to the CVC which would be problematic from a PCI compliance point of view.)
At this time, Stripe doesn't provide a way to check the CVC of saved cards. The CVC is checked once, when you initially create the customer object using the card token, or add a card to an existing customer object. It is not possible (for now) to "revalidate" the CVC at later times.
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',
})
I'm using ActiveMerchant to process a recurring payment. I want the payment to have a limited number of occurence but even if I pass the 'cycles' parameters my payment has no end or any trace of limited number of occurence when I go to see the results of my transaction in the sandbox site ??
Here is my gateway definition :
config.after_initialize do
ActiveMerchant::Billing::Base.mode = :test
paypal_options = {
login: "my_api.ca",
password: "QNBW72G3Q999999",
signature: "AFcWxV21C7fd0v3bYYYRCpSSRl31AmVtuyteuytuetwuytwtwEyY5cTGMA"
}
::MY_PAYMENT_GATEWAY = ActiveMerchant::Billing::PaypalCaGateway.new(paypal_options)
end
And here is my code to process the recurring payment :
response = MY_PAYMENT_GATEWAY.recurring(amount,
#publisher.credit_card.active_merchant_credit_card,
{:ip => request.remote_ip,
:email => current_publisher.user.email,
:period => 'Month',
:frequency => 1,
:cycles => #chosen_package.duration.to_i,
:start_date => Time.now.to_date,
:description => "Try to pay only #chosen_package.duration times !? "})
My comprehension is that the 'cycles' parameters should reflect as a maximum number of charge in sandbox test site but I'm stuck... like like it's not working !?
Any help appreciated ! Thx a lot !
Serge
I have found it by digging into ActiveMerchant source... The good parameters name is :total_billing_cycles, not :cycles as stated in the documentation that I have...
Work like a charm now :-)
I'm using ActiveMerchant with Braintree as my payment processor. I want to take advantage of Braintree's customer vault functionality to store credit card info.
Storage goes fine, but I can't figure out the correct way to charge the credit card with the customer_vault_id. It seems very straight-forward according to the Braintree documentation, but I'm not sure how to pass this through ActiveMerchant. I get validation errors from Braintree if I send a credit card with empty data, and errors from ActiveMerchant if I try nil. The only thing that seems obvious is to send the customer_vault_id in the purchase_options hash, like:
GATEWAY.purchase(self.price_in_cents, self.credit_card,
:ip => self.ip_address,
:customer_vault_id => 12345)
Is this the correct way to use a stored customer vault?
If so, what is the correct second argument for this line if I want to use a stored customer vault as payment method?
Thanks.
I discovered that you can substitute the customer_vault_id as a string for the ActiveMerchant::Billing::CreditCard in the purchase method. The docs really don't have any indication of this :(
After you call #store on the gateway, you will get a response, which you need to store the authorization.
Per the docs found in the wiki: https://github.com/activemerchant/active_merchant/wiki/Patterns-&-Standards
store
It's critical that store returns a token that can be used against purchase and authorize. Currently the standard is to return the token in the Response#authorization field.
payment method
String/token: Representation of a payment method tokenized via store
e.g.
gateway = ActiveMerchant::Billing::BraintreeGateway.new(login: login, password: password)
credit_card = ActiveMerchant::Billing::CreditCard.new(
:first_name => 'Bob',
:last_name => 'Bobsen',
:number => '4242424242424242',
:month => '8',
:year => Time.now.year+1,
:verification_value => '000')
response = gateway.store(credit_card)
=> #<ActiveMerchant::Billing::Response:0x00007f8efb3df1a8
#authorization="1508682289#1508160804#cim_store",
#avs_result={"code"=>nil, "message"=>nil, "street_match"=>nil, "postal_match"=>nil},
#cvv_result={"code"=>nil, "message"=>nil},
#emv_authorization=nil,
#error_code=nil,
#fraud_review=false,
#message="Successful",
#params=
{"message_code"=>"1",
"message_text"=>"Successful",
"result_code"=>"Ok",
"test_request"=>nil,
"customer_profile_id"=>"1508682289",
"customer_payment_profile_id"=>"1508160804",
"direct_response"=>nil},
#success=true,
#test=true>
response.authorization
=> "1508682289#1508160804#cim_store"
gateway.purchase(100, response.authorization)
=> #<ActiveMerchant::Billing::Response:0x00007f8ede0027c8
#authorization="40036062888#XXXX4242#cim_purchase",
#avs_result=
{"code"=>"Y", "message"=>"Street address and 5-digit postal code match.", "street_match"=>"Y", "postal_match"=>"Y"},
#cvv_result={"code"=>"P", "message"=>"CVV not processed"},
#emv_authorization=nil,
#error_code=nil,
#fraud_review=false,
#message="This transaction has been approved.",
#params=
{"message_code"=>"1",
"message_text"=>"Successful",
"result_code"=>"Ok",
"test_request"=>nil,
"customer_profile_id"=>nil,
"customer_payment_profile_id"=>nil,
"direct_response"=>
"1,1,1,This transaction has been approved.,T91GL2,Y,40036062888,,,1.00,CC,auth_capture,2852040810cf440a4a13,Bob,Bobsen,,,,n/a,,,,,,,,,,,,,,,,,,,,P,2,,,,,,,,,,,XXXX4242,Visa,,,,,,,,,,,,,,,,,",
"response_code"=>1,
"response_subcode"=>"1",
"response_reason_code"=>"1",
"response_reason_text"=>"This transaction has been approved.",
"approval_code"=>"T91GL2",
"avs_result_code"=>"Y",
"transaction_id"=>"40036062888",
"invoice_number"=>"",
"order_description"=>"",
"amount"=>"1.00",
"method"=>"CC",
"transaction_type"=>"auth_capture",
"customer_id"=>"2852040810cf440a4a13",
"first_name"=>"Bob",
"last_name"=>"Bobsen",
"company"=>"",
"address"=>"",
"city"=>"",
"state"=>"n/a",
"zip_code"=>"",
"country"=>"",
"phone"=>"",
"fax"=>"",
"email_address"=>"",
"ship_to_first_name"=>"",
"ship_to_last_name"=>"",
"ship_to_company"=>"",
"ship_to_address"=>"",
"ship_to_city"=>"",
"ship_to_state"=>"",
"ship_to_zip_code"=>"",
"ship_to_country"=>"",
"tax"=>"",
"duty"=>"",
"freight"=>"",
"tax_exempt"=>"",
"purchase_order_number"=>"",
"md5_hash"=>"",
"card_code"=>"P",
"cardholder_authentication_verification_response"=>"2",
"account_number"=>"XXXX4242",
"card_type"=>"Visa",
"split_tender_id"=>"",
"requested_amount"=>"",
"balance_on_card"=>""},
#success=true,
#test=true>