⚙️ Integration
Loading...
Use the Payment Element: Save a Payment Method test integration to save an arbitrary Payment Method to reuse here, or press the "Create a Demo Customer" button below to do the following:
- Create a demo Customer
- Create and confirm a Setup Intent to attach
pm_card_visa
to the demo Customer - Update the Payment Method's
allow_redisplay
property totrue
- Reload this page with the Customer's ID in a query parameter so the Payment Element can be loaded with a Customer Session set to display the Customer's saved Payment Method
🧑💻 Code
<?php
$stripeConfiguration = [
'api_key' => 'sk_•••',
'stripe_version' => '2023-10-16',
];
$stripe = new \Stripe\StripeClient($stripeConfiguration);
if (isset($_GET['createDemoCustomer'])) {
$customer = $stripe->customers->create([
'description' => 'Reuse Payment Method Demo Customer',
]);
// This would normally be confirmed client-side so the customer could handle any potential next actions
$setupIntent = $stripe->setupIntents->create([
'customer' => $customer->id,
'payment_method' => 'pm_card_visa',
'confirm' => true,
'automatic_payment_methods' => [
'enabled' => true,
'allow_redirects' => 'never',
],
]);
// This would normally be set automatically when the customer checks the save box in the Payment Element
$paymentMethod = $stripe->paymentMethods->update($setupIntent->payment_method, [
'allow_redisplay' => 'always',
]);
header('Content-Type: application/json');
echo json_encode([
'customerID' => $customer->id,
]);
exit;
}
else if (isset($_GET['prepareToPay'])) {
$customerID = $_GET['prepareToPay'];
$customerSession = $stripe->customerSessions->create([
'customer' => $customerID,
'components' => [
'payment_element' => [
'enabled' => true,
'features' => [
'payment_method_save' => 'enabled',
'payment_method_save_usage' => 'off_session',
'payment_method_redisplay' => 'enabled',
'payment_method_remove' => 'enabled',
],
],
],
]);
$paymentIntent = $stripe->paymentIntents->create([
'customer' => $customerID,
'amount' => 4200,
'currency' => 'usd',
]);
header('Content-Type: application/json');
echo json_encode([
'paymentIntentClientSecret' => $paymentIntent->client_secret,
'customerSessionClientSecret' => $customerSession->client_secret,
]);
exit;
}
<script src="https://js.stripe.com/v3/"></script>
<p id="loading">Loading...</p>
<section id="demoCustomer" hidden>
<p>Use the <a href="/test/payment-element-save/">Payment Element: Save a Payment Method</a> test integration to save an arbitrary Payment Method to reuse here, or press the "Create a Demo Customer" button below to do the following:</p>
<ul>
<li>Create a demo <a href="https://docs.stripe.com/api/customers">Customer</a></li>
<li>Create and confirm a <a href="https://docs.stripe.com/api/setup_intents">Setup Intent</a> to attach <code>pm_card_visa</code> to the demo Customer</li>
<li>Update the Payment Method's <a href="https://docs.stripe.com/api/payment_methods/update#update_payment_method-allow_redisplay"><code>allow_redisplay</code> property</a> to <code>true</code></li>
<li>Reload this page with the Customer's ID in a query parameter so the <a href="https://docs.stripe.com/js/element/payment_element">Payment Element</a> can be loaded with a <a href="https://docs.stripe.com/api/customer_sessions">Customer Session</a> set to display the Customer's saved Payment Method</li>
</ul>
<p><button type="button" id="createDemoCustomer">Create Demo Customer</button></p>
</section>
<section id="paymentForm" hidden>
<p class="customerInfo"></p>
<p id="payment-element"></p>
<p><button type="button" id="pay">Pay</button></p>
</section>
<pre id="output"></pre>
#payment-element {
/* Provides a visual outline of the Element */
border: solid 1px;
/* Required for dark mode legibility */
background-color: white;
/* Aesthetics */
padding: 1rem;
border-radius: .25rem;
}
const thisPath = '/test/payment-element-reuse';
const loadingElement = document.querySelector('#loading');
const demoCustomerSection = document.querySelector('#demoCustomer');
const createDemoCustomerButton = document.querySelector('#createDemoCustomer');
createDemoCustomerButton.addEventListener('click', createDemoCustomer);
const paymentFormSection = document.querySelector('#paymentForm');
const paymentFormCustomerInfoElement = document.querySelector('#paymentForm .customerInfo');
const payButton = document.querySelector('#pay');
const outputElement = document.querySelector('#output');
const urlSearchParams = new URLSearchParams(window.location.search);
const stripe = Stripe('pk_test_51O2hxMC4JnNRtz8VToJJbGHrFTPPr6TkP09h7ql3YJaqpNcxoSNxtk38glyzi9VrZKStns858YynOO2ZyGmU7VRi00CIUWuUdk');
async function createDemoCustomer() {
const result = await fetch('?createDemoCustomer');
const response = await result.json();
window.location.href = thisPath + '?customer=' + response.customerID;
}
async function prepareToPay() {
const customerID = urlSearchParams.get('customer');
const result = await fetch('?prepareToPay=' + customerID);
const response = await result.json();
paymentFormCustomerInfoElement.innerHTML = 'Customer Session created for <code>' + customerID + '</code><br><small><a href="/test/payment-element-reuse/">Stop using this Customer</a></small>';
const elements = stripe.elements({
clientSecret: response.paymentIntentClientSecret,
customerSessionClientSecret: response.customerSessionClientSecret,
});
const paymentElement = elements.create('payment');
paymentElement.mount('#payment-element');
payButton.addEventListener('click', async (event) => {
outputElement.innerHTML = 'Processing...';
const {error} = await stripe.confirmPayment({
elements: elements,
confirmParams: {
return_url: window.location.href,
}
});
if (error) {
outputElement.textContent = 'Error: Unable to confirm payment: ' + error.message;
console.log({error});
}
});
loadingElement.hidden = true;
}
// If there's no Customer ID, display the form to create a demo Customer
if (!urlSearchParams.has('customer')) {
demoCustomerSection.hidden = false;
loadingElement.hidden = true;
}
// If there is a Customer ID, initialize and display the Payment Element
else {
paymentFormSection.hidden = false;
prepareToPay();
}
// If the URL contains a Payment Intent's client secret, retrieve the Setup Intent and display it
if (urlSearchParams.has('payment_intent_client_secret')) {
stripe.retrievePaymentIntent(urlSearchParams.get('payment_intent_client_secret')).then(result => {
if (result.error) {
output.textContent = "Unable to retrieve Payment Intent using client secret in URL:\n\n" + JSON.stringify(result.error, null, 2);
return;
}
output.textContent = "Payment Intent retrieved using client secret in URL:\n\n" + JSON.stringify(result.paymentIntent, null, 2);
});
}