Stripe Laravel not getting some params from Checkout Form - php

For some reason, some parameters such as amount, and description are not being passed on from the Form to the Controller.
The token is generated and the email is sent too, but not the other params.
In order for the Payment to work I have to enter manually the amount at the controller.
<form action="checkout" method="POST">
<script
src="https://checkout.stripe.com/checkout.js" class="stripe-button"
data-key= "pk_test_zOi8g9ztDo1HNeC6iFFTWqwk"
data-amount="1500"
data-name="Demo Site"
data-description="2 shoes ($20.00)"
data-image="/128x128.png">
</script>
</form>
=====================================
public function PostPaymentData(){
Stripe::setApiKey('sk_test_CvCavCI3G4onNbKxZEaNzkvZ');
// get the data submitted by the CHECK OUT Form
$token = Input::get('stripeToken'); (it gets it)
$amount = Input::get('amount'); (it does not get it)
$description = Input::get('description');(it does not get it)
echo "the amount is . $amount"; //nothing
echo "the description is $description"; // nothing
print_r(input::all()); // it just prints the token and the email
// create the charge on STRIPE servers. This will charge the credit card
try {
$charge = Stripe_Charge::create(array(
"amount" => 1800, // amount in cents, again (I have to enter it manually because $amount = ' ';
"currency" => "usd",
"card" => $token,
"description" => "holycow#gmail.com")
);
}
catch(Stripe_CardError $e) {
// Since it's a decline, Stripe_CardError will be caught
dd($e);
=================================================
Route::get('payments/getpaymentpage', array(
'as'=>'getpaymentpage',
'uses'=>'StripePay#getPaymentPage'
));
Route::post('payments/checkout', array(
'as'=>'checkout',
'uses'=>'StripePay#PostPaymentData'
));
My config for Stripe:
In the providers:
'Abodeo\LaravelStripe\LaravelStripeServiceProvider'
In the composer json
"stripe/stripe-php": "1.*",
"abodeo/laravel-stripe": "dev-master"

Well, it was the support staff from Stripe (very kind people) who has given me the answer:
It's actually expected that the amount doesn't get sent with the token to your server. If it did, the user could easily tamper with it via developer tools or writing javascript snippets, etc. Usually you'll want the price of something to be in your database somewhere (a product or whatever you're selling) and look it up again once you receive the token to get the authoritative price.
But sometimes you've got a situation where the user specifies the price somehow, and that is intentional. In that case I suggest making a hidden form element:
And then populating that with JavaScript using a callback. If you're using Stripe.js you already have a response handler you can use for this, just populate the field before you POST your data. If you're using Stripe Checkout, then you can use the token callback on the handler using the custom integration.

Related

Saving card details to customer using Stripe Elements

I have a little store I'm setting up, and so far, it's relatively simple. You can either order the product one time, weekly, or monthly.
I have set up the corresponding products in the Stripe Dashboard.
If the client sends that they want a recurring order, it creates a Customer with their information.
But whenever I try and create a recurring order, I receive a This customer has no attached payment source or default payment method. thrown in.
I'm using Stripe Elements, and since the card data never goes to my server, I'm not sure how to go about adding a payment method to this Customer.
Create subscription:
\Stripe\Subscription::create([
'customer' => $customer_id,
'items' => [
[
'price' => 'price_id_2',
'quantity' => $qty_1,
'price' => 'price_id_2',
'quantity' => $qty_2,
],
],
]);
$.post to send data to the PHP file
$.post('./secret.php', data, null, "json")
.done(function(data) {
clientSecret = data.client_secret;
stripe.confirmCardPayment(clientSecret, {
payment_method: {
card: card,
}
}).then(function(result) {
if (result.error) {
console.log(result.error.message);
} else {
if (result.paymentIntent.status === 'succeeded') {
console.log("Payment success.");
document.getElementById("processing").classList.add("hide");
document.getElementById("order-success").classList.remove("hide");
}
}
})
})
.fail(function(xhr, status, error) {
document.getElementById("processing").classList.add("hide");
document.getElementById("order-failure").classList.remove("hide");
});
My one-time order works fine, but I just can't understand how to do this. The Docs show "Saving Card Data" as a deprecated utility, so I'm not sure what to do.
It sounds like you likely want to save a card during the payment process: https://stripe.com/docs/payments/save-during-payment

How to add multiple cards in same customer in stripe payment gateway using php

i was implementing stripe payment in testing mode.Here i got an error like Same token is used again. is there any different way to add multiple cards.
or i need to call retrive function in a separate page so that conflict of same token never come again.And how should i set a card default.
public function createToken($data)
{
$TokenResult=Token::create(array(
"card" => array(
"name" => $data['name'],
"number" => $data['card_number'],
"exp_month" => $data['month'],
"exp_year" => $data['year'],
"cvc" => $data['cvc']
)));
//echo "<pre>";;
//print_r($TokenResult);
$this->token=$TokenResult['id'];//store token id into token variable
$this->chargeCard($this->token); //call chargecard function via passing token id
}
/*
* function to create customer
*/
public function createCustomer($data,$token=null)//pass form data and token id
{
$customer=Customer::create(array(
"email"=>$data['email'],
"description" => $data['name'],
"source" => $token // obtained with Stripe.js
));
$customerId=$customer['id'];
$this->retriveCustomer($customerId,$token);
}
/*
* function to retrive current customers for adding multiple cards to same customers*/
public function retriveCustomer($customerid,$token)
{
echo $this->token;
//die('here');
$retriveResult=Customer::retrieve($customerid);
$retriveResult->sources->create(array("source" =>$this->token));
return $retriveResult;
}
First, please note that unless you are PCI certified and allowed to directly manipulate card data, you should never have access to card numbers in your server-side code.
Card tokens should be created client-side, via Checkout or Elements. Your server should only deal with client-side created card tokens and never with PCI-sensitive information (card numbers and CVCs). This will greatly decrease the burden of PCI compliance and make you eligible for PCI SAQ A.
In PHP, this is how you'd add a card to an existing customer object:
$customer = \Stripe\Customer::retrieve("cus_...");
$card = $customer->sources->create(array(
"source" => $token // token created by Checkout or Elements
));
I think you dont need to create a token in case of adding new card. It helps while you update certain card. So the flow of addition will be same as you created for first card.
I dont know which stripe version you are using, I am using bit old:
$card_array = array(
'card' => array(
'number' => $number,
'exp_month' => $exp_month,
'exp_year' => $exp_year,
'cvc' => $cvc,
'name' => $name
)
);
$card_obj = $this->setData("\Stripe\Customer", "retrieve", $customer_id, TRUE);
$card = $card_obj->sources->create($card_array);
Stripe's docs don't explain a lot of the more nuanced procedures so you have to do a lot of testing.
Assuming you have a customer object $cu, with the token you get from checkout or whatever you use:
$card = $cu->sources->create(['source'=>$token]);
will add a card to the customer. It just adds the card to the list; subsequent calls will add cards to the list. Note that it does not check for duplicates, so the same card can be on the list multiple times. It will also not set the new card to the active card. To make a card the default (or active), use
$cu->default_source = $card
$cu->save();
Using the older card interface:
$cu->card = $token;
$cu->save();
The new card will replace the default card. It will NOT make the previously default card inactive; it will delete the current default and make the new card the active default. The card interface is the easiest if you're just allowing 1 card to be attached to a customer at a time.

Magento Credit card number mismatch with credit card type exception

I am using stripe credit card payment method for website on my magento store and developing a mobile application. I am developing the api's using native magento api. Problem occurred on create order api, everything till adding payment for stripe credit card works fine but when I hit the create order api it throws the exception.
"Credit card number mismatch with credit card type exception"
Below is api code, Please share your knowledge for this issue. Thanks in advance.
$proxy = new SoapClient($this->_client); //soap handle
$sessionId = $proxy->login($this->_apiuser, $this->_apikey);
$resultCustomerAddresses = $proxy->call($sessionId, "cart_customer.addresses", array($shoppingCartId, $arrAddresses));
if ($resultCustomerAddresses != TRUE)
{
return json_encode(array('status' => 0, 'result' => array(),'message' => 'Error in saving address'));
}
$resultShippingMethods = $proxy->call($sessionId, "cart_shipping.list", array($shoppingCartId));
$randShippingMethodIndex = rand(0, count($resultShippingMethods)-1 );
$shippingMethod = $resultShippingMethods[$randShippingMethodIndex]["code"];
$resultShippingMethod = $proxy->call($sessionId, "cart_shipping.method", array($shoppingCartId, $shipping_method));
//$resultTotalOrder = $proxy->call($sessionId,'cart.totals',array($shoppingCartId));
$paymentMethod = array(
"method" => $payment_method
);
$resultPaymentMethod = $proxy->call($sessionId, "cart_payment.method", array($shoppingCartId, $payment_method));
$licenseForOrderCreation = null;
$resultOrderCreation = $proxy->call($sessionId,"cart.order",array($shoppingCartId, null, $licenseForOrderCreation));
I had the same problem and successfully solved it, see this answer: https://stackoverflow.com/a/41948259/1052675
Basically, you supply the card information before you save the quote. It will validate the card against regex patterns and configured purchase limits and make sure you can use the payment method.
Then it will forget the payment information.
So before you tell it to submit the order, you need to supply the card info again.
My solution was a custom endpoint for simplicity on the front end app and it enabled me to keep the card info in memory to re-save between saving the quote and submitting the order.

Stripe doubles anything

I am using a function I created that I have tried creating customers from, and creating charges from. For whatever reason it seems to be double charging in test mode (Not bringing into live mode under these conditions) and I'm trying to understand why. I had it going through a few functions so I made it all happen in one function to make sure that it had nothing to do with what I had made. I'm lost on why this is happening. I try to make charges from token, doubles in less than a second. I try to create a customer from token, doubles in less than a second. I am using Stripes latest stripe-php library.
public function invoice($invoice = null) {
//Provides billing info for invoice.ctp
$this->loadModel('Invoice');
$billingi = $this->Invoice->get($invoice, [
'contain' => ['Items'],
]);
$dollars = 0;
foreach ($billingi->items as $item) {
$dollars += $item->price;
}
$cents = bcmul($dollars, 100);
$price = floatval($cents);
if ($this->request->is('post')) {
$stripeToken = $this->request->data('stripeToken');
//Sets stripe API
\Stripe\Stripe::setApiKey("sk_test_QVYouMViTf1k3zfVu2VAyZge");
//Retrieves stripe token from stripe API
//$response = \Stripe\Token::retrieve($stripeToken);
\Stripe\Customer::create(array(
"description" => "Test customer",
"source" => $stripeToken // obtained with Stripe.js
));
$this->Flash->success(__('Thank you for your payment!'));
return $this->redirect(['action' => 'approved', $invoice]);
}
/*
if ($response && $this->checkExists($response->card->cvc_check, $response->card->address_zip_check) == true) {
$this->insertCharge($invoice, $response, $price);
} else {
//Throw error because cvc_check or zip came back null (doesn't exist)
}
}
*/
$this->set('billingi', $billingi);
$this->set('_serialize', ['billing']);
}
The reason why there are things commented out is because I wanted to test the function without it, but adding it back later when I understand what the issue is.
In your code, the only API request sent to Stripe is a customer creation request (\Stripe\Customer::create(...)).
This doesn't charge the user -- it merely validates the card from the token in the source parameter, and creates a persistent customer object that you can in turn use to create actual charges. This tutorial explains this flow.
There's nothing in your code that would cause the API request to be sent twice. It's very unlikely the issue is on Stripe's end. More likely, your code is being called twice for some reason that's not related to Stripe. You'd need to add traces to your code to figure out what exactly is being called in what order.

Stripe billing with same price as form

So I wish to bill customers (who are not users) the same amount as what is displayed in the stripe form
<form action="/charge" method="POST">
{!! csrf_field() !!}
<script
src="https://checkout.stripe.com/checkout.js" class="stripe-button"
data-key="pk_test_key"
data-amount="{{ $note->price*100 }}"
data-name="Hello World"
data-description="{{$note->title}}"
data-image="/img/documentation/checkout/marketplace.png"
data-locale="auto"
data-currency="aud">
</script>
</form>
In the form the price displayed is the price listed in the relevant note model * 100. I would like the customer to actually be billed this value, it will change depending upon the note.
Here is my server billing
public function charge()
{
// Set your secret key: remember to change this to your live secret key in production
// See your keys here https://dashboard.stripe.com/account/apikeys
\Stripe\Stripe::setApiKey("sk_test_key");
// Get the credit card details submitted by the form
$token = $_POST['stripeToken'];
// Create the charge on Stripe's servers - this will charge the user's card
try {
$charge = \Stripe\Charge::create(array(
"amount" => 100, // amount in cents, again
"currency" => "aud",
"source" => $token,
"description" => "Example charge"
));
} catch(\Stripe\Error\Card $e) {
// The card has been declined
}
return 'payment succesful';
}
I need to set the "amount" equal to the note value.
Otherwise, payment is going through on my cashier test account and mostly everything else needs to be working.
The customers are not registered users though.
The amount needs to be something that you calculate server side, otherwise people can just modify the DOM and pass whatever amount they would like.
Instead, store the id in the cache on the server side, and pass the note in as a dependency to the charge function, then compare the 2.
/**
* Assuming name of "view" page
*/
public function checkout(Note $note)
{
/**
* Always forget this on each page load, so we can switch seamlessly between Notes.
*/
Illuminate\Support\Facades\Cache::forget('nid')->put('nid', $note->id);
}
Don't forget to modify the charge route to include the new reference to our Note dependency
route::post('charge/{note}', 'Controller#charge')->name('charge');
Make sure to update your form to pass the note as well
<form action="{{route('charge', $note)}}" method="POST">
sidenote I like named routes, but it's not required.
Then when you're processing the request, compare the $nid and the $note->id
public function charge(Illuminate\Http\Request $request, Note $note)
{
$nid = Illuminate\Support\Facades\Cache::get('nid');
// id's match, no sneaky stuff. safe to use $note->price now
if ($nid === $note->id) {
//now we can process our payment.
// Set your secret key: remember to change this to your live secret key in production
// See your keys here https://dashboard.stripe.com/account/apikeys
\Stripe\Stripe::setApiKey("sk_test_key");
// Get the credit card details submitted by the form
$token = $request->get('stripeToken');
// Create the charge on Stripe's servers - this will charge the user's card
try {
$charge = \Stripe\Charge::create(array(
"amount" => number_format($note->price, 0, '', ''), // amount in cents, again
"currency" => "aud",
"source" => $token,
"description" => "Example charge"
));
} catch(\Stripe\Error\Card $e) {
// The card has been declined
}
}
}

Categories