Skip to content

Instantly share code, notes, and snippets.

@thorwebdev
Last active August 11, 2019 23:36
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save thorwebdev/d1793c1a565f45eed606ccfd52c3fc81 to your computer and use it in GitHub Desktop.
Save thorwebdev/d1793c1a565f45eed606ccfd52c3fc81 to your computer and use it in GitHub Desktop.
Best practice example for creating one time charges using Stripe.js and Stripe's PHP bindings without creating customer objects.
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>One Time Charge</title>
<script type="text/javascript" src="https://js.stripe.com/v2/"></script>
</head>
<body>
<?php
require __DIR__ . '/vendor/autoload.php'; // Install PHP library: https://stripe.com/docs/libraries#php-library
// Only execute if form has been submitted
if ($_POST) {
// PART 2 - Server Side (please scroll down to the script tag at the end of the body tag for PART 1)
// Create one time Charge
// https://stripe.com/docs/charges
// 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_***");
// Get the credit card details submitted by the form
$token = $_POST['stripeToken'];
// Add email address to metadata to make it searchable in the dashboard
$metadata = array(
"cardholder_name"=>$_POST['cardholder_name'],
"recipient_name"=>$_POST['shipping_name'],
"email"=>$_POST['email'],
"phone"=>$_POST['shipping_phone'],
"recipient_city"=>$_POST['shipping_address_city'],
"recipient_country"=>$_POST['shipping_address_country']
);
// Add shipping information if physical product
$shipping = array(
"name"=>$_POST['shipping_name'],
"phone"=>$_POST['shipping_phone'],
"address"=>array(
"city"=>$_POST['shipping_address_city'],
"country"=>$_POST['shipping_address_country'],
"line1"=>$_POST['shipping_address_line1'],
"line2"=>$_POST['shipping_address_line2'],
"postal_code"=>$_POST['shipping_address_postal_code'],
"state"=>$_POST['shipping_address_state'],
),
"carrier"=>"Fedex", // could also be updated later https://stripe.com/docs/api/php#update_charge
"tracking_number"=>"fedex_12345"
);
// Add email address to description for risk scoring
$description = 'Order from ' . $_POST['email'];
// Create the charge on Stripe's servers - this will charge the user's card
try {
$charge = \Stripe\Charge::create(array(
"amount" => 1000, // amount in cents
"currency" => "usd",
"source" => $token,
"description" => $description,
"metadata" => $metadata,
"shipping" => $shipping
));
$chargeID = $charge['id'];
print("\n" . 'Successfuly created charge with ID: <a target="_blank" href="https://dashboard.stripe.com/test/payments/' . $chargeID . '">' . $chargeID . '</a>' . "\n");
} catch(\Stripe\Error\Card $e) {
// Since it's a decline, \Stripe\Error\Card will be caught
$body = $e->getJsonBody();
$err = $body['error'];
print('Status is:' . $e->getHttpStatus() . "\n");
print('Type is:' . $err['type'] . "\n");
print('Code is:' . $err['code'] . "\n");
// param is '' in this case
print('Param is:' . $err['param'] . "\n");
print('Message is:' . $err['message'] . "\n");
} catch (\Stripe\Error\RateLimit $e) {
// Too many requests made to the API too quickly
} catch (\Stripe\Error\InvalidRequest $e) {
// Invalid parameters were supplied to Stripe's API
} catch (\Stripe\Error\Authentication $e) {
// Authentication with Stripe's API failed
// (maybe you changed API keys recently)
} catch (\Stripe\Error\ApiConnection $e) {
// Network communication with Stripe failed
} catch (\Stripe\Error\Base $e) {
// Display a very generic error to the user, and maybe send
// yourself an email
} catch (Exception $e) {
// Something else happened, completely unrelated to Stripe
}
}
?>
<!-- Your custom HTML checkout form -->
<h1>Charge $10 with Stripe</h1>
<form action="" method="POST" id="payment-form">
<span class="payment-errors"></span>
<h2>Input for Token creation</h2>
<!-- https://stripe.com/docs/stripe.js#collecting-card-details -->
<div class="form-row">
<label>
<span>Card Number</span>
<input type="text" size="20" data-stripe="number" value="4242424242424242" />
</label>
</div>
<div class="form-row">
<label>
<span>CVC</span>
<input type="text" size="4" data-stripe="cvc" value="123" />
</label>
</div>
<div class="form-row">
<label>
<span>Card Expiration Date (MM/YYYY)</span>
<input type="text" size="2" data-stripe="exp-month" value="01" />
</label>
<span> / </span>
<input type="text" size="4" data-stripe="exp-year" value="2020" />
</div>
<div class="form-row">
<label>
<span>Cardholder Name</span>
<input type="text" size="50" name="cardholder_name" data-stripe="name" value="Father McStripe" />
</label>
</div>
<div class="form-row">
<label>
<span>Billing Address (line 1)</span>
<input type="text" size="50" data-stripe="address_line1" value="3180 18th Street" />
</label>
</div>
<div class="form-row">
<label>
<span>Billing Address (line 2)</span>
<input type="text" size="50" data-stripe="address_line2" value="" />
</label>
</div>
<div class="form-row">
<label>
<span>Billing Address City</span>
<input type="text" size="50" data-stripe="address_city" value="San Francisco" />
</label>
</div>
<div class="form-row">
<label>
<span>Billing Address State</span>
<input type="text" size="25" data-stripe="address_state" value="CA" />
</label>
</div>
<div class="form-row">
<label>
<span>Billing Address ZIP / Postal code</span>
<input type="text" size="10" data-stripe="address_zip" value="94110" />
</label>
</div>
<div class="form-row">
<label>
<span>Billing Address Country</span>
<input type="text" size="25" data-stripe="address_country" value="United States" />
</label>
</div>
<h2>Inpute for Charge creation</h2>
<div class="form-row">
<label>
<span>Customer Email</span>
<input type="text" size="50" name="email" value="stripey@mcstripe.com" />
</label>
</div>
<h3>Shipping Information</h3>
<!-- https://stripe.com/docs/api#charge_object-shipping -->
<div class="form-row">
<label>
<span>Recipient Name</span>
<input type="text" size="50" name="shipping_name" value="Son McStripe" />
</label>
</div>
<div class="form-row">
<label>
<span>Recipient Phone</span>
<input type="text" size="50" name="shipping_phone" value="(415) 688-4253" />
</label>
</div>
<div class="form-row">
<label>
<span>Shipping Address (line 1)</span>
<input type="text" size="50" name="shipping_address_line1" value="3180 18th Street" />
</label>
</div>
<div class="form-row">
<label>
<span>Shipping Address (line 2)</span>
<input type="text" size="50" name="shipping_address_line2" value="" />
</label>
</div>
<div class="form-row">
<label>
<span>Shipping Address City</span>
<input type="text" size="50" name="shipping_address_city" value="San Francisco" />
</label>
</div>
<div class="form-row">
<label>
<span>Shipping Address State</span>
<input type="text" size="25" name="shipping_address_state" value="CA" />
</label>
</div>
<div class="form-row">
<label>
<span>Shipping Address ZIP / Postal code</span>
<input type="text" size="10" name="shipping_address_postal_code" value="94110" />
</label>
</div>
<div class="form-row">
<label>
<span>Shipping Address Country</span>
<input type="text" size="25" name="shipping_address_country" value="United States" />
</label>
</div>
<button type="submit">Submit Payment</button>
</form>
<script>
// PART 1 - Client Side
// Create the card token using Stripe.js
// set Stripe publishable key: remember to change this to your live secret key in production
// See your keys here https://dashboard.stripe.com/account/apikeys
Stripe.setPublishableKey('pk_test_***');
// grab payment form
var paymentForm = document.getElementById("payment-form");
// listen for submit
paymentForm.addEventListener("submit", processForm, false);
/* Methods */
// process form on submit
function processForm(evt) {
// prevent form submission
evt.preventDefault();
// create stripe token
Stripe.card.createToken(paymentForm, stripeResponseHandler);
};
// handle response back from Stripe
function stripeResponseHandler(status, response) {
// if an error
if (response.error) {
// respond in some way
alert("Error: " + response.error.message);
}
// if everything is alright
else {
// creates a token input element and add that to the payment form
var token = document.createElement("input");
token.name = "stripeToken";
token.value = response.id; // token value from Stripe.card.createToken
token.type = "hidden"
paymentForm.appendChild(token);
// resubmit form
alert("Form will submit!\n\nToken ID = " + response.id);
// uncomment below to actually submit
paymentForm.submit();
}
};
</script>
</body>
</html>
@tigmick
Copy link

tigmick commented Feb 4, 2018

how can i use the stripe form instead of yours

@ennisa-ire
Copy link

Nice one, all in one place, thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment