Last active
August 11, 2019 23:36
-
-
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!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="[email protected]" /> | |
</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> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
how can i use the stripe form instead of yours