user6369603
user6369603

Reputation:

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.

Upvotes: 2

Views: 381

Answers (1)

Ohgodwhy
Ohgodwhy

Reputation: 50767

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
        }    
    }
}

Upvotes: 2

Related Questions