Verify CVC code before creating charge - ruby-on-rails

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.

Related

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.

No such customer: cus_************ (Stripe::InvalidRequestError) when customer exists

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

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',
})

Stripe charge and Subscription

I have a rails 4 app that I'm using Stripe checkout. I've followed their tutorial, and my controller looks like:
def create
s = Subscription.new
s.user_id = current_user.id
s.plan_id = params[:plan_id]
s.stripe_token = params[:stripeToken]
s.save
# Amount in cents
#amount = 699
customer = Stripe::Customer.create(
:email => current_user.email,
:card => params[:stripeToken]
)
charge = Stripe::Charge.create(
:customer => customer.id,
:amount => #amount,
:description => 'Sitekite Pro',
:currency => 'usd'
)
rescue Stripe::CardError => e
flash[:error] = e.message
redirect_to charges_path
end
I looked at a couple other tutorials, looking for help with creating a subscription with Stripe checkout. Some of them dont have the Stripe::Charge part. Is the Stripe::Charge part only for single charges? How do I sign the user up for a monthly subscription with the same #amount?
The Stripe::Charge is indeed for single charges. The Customer create is what you need, but when you create the customer you specify a plan (plans are defined in your Stripe dashboard). The plan will specify the amount to charge and how often to charge it.
When the charge is actually made, which might be the same day or might be several days later depending on whether your plan provides, say, some free access time... the Stripe service can send the charge to a webhook... which is to say a route in your project for the dedicated use of the Stripe service.
Stripe will post charges (and failures) to your webhook, and you can handle them appropriately (logging the payments and maybe restricting the user if his card becomes expired or a regular payment fails for some other reason)

How do I use a stored payment source for a purchase in ActiveMerchant?

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>

Resources