· 5 years ago · Jun 03, 2020, 12:04 PM
1<!DOCTYPE html>
2<head>
3 <title>Checkout</title>
4 <script src="https://js.stripe.com/v3/"></script>
5 <style>
6 /* Variables */
7* {
8 box-sizing: border-box;
9}
10body {
11 font-family: -apple-system, BlinkMacSystemFont, sans-serif;
12 font-size: 16px;
13 -webkit-font-smoothing: antialiased;
14 display: flex;
15 justify-content: center;
16 align-content: center;
17 height: 100vh;
18 width: 100vw;
19}
20form {
21 width: 30vw;
22 min-width: 500px;
23 align-self: center;
24 box-shadow: 0px 0px 0px 0.5px rgba(50, 50, 93, 0.1),
25 0px 2px 5px 0px rgba(50, 50, 93, 0.1), 0px 1px 1.5px 0px rgba(0, 0, 0, 0.07);
26 border-radius: 7px;
27 padding: 40px;
28}
29input {
30 border-radius: 6px;
31 margin-bottom: 6px;
32 padding: 12px;
33 border: 1px solid rgba(50, 50, 93, 0.1);
34 height: 44px;
35 font-size: 16px;
36 width: 100%;
37 background: white;
38}
39.result-message {
40 line-height: 22px;
41 font-size: 16px;
42}
43.result-message a {
44 color: rgb(89, 111, 214);
45 font-weight: 600;
46 text-decoration: none;
47}
48.hidden {
49 display: none;
50}
51#card-error {
52 color: rgb(105, 115, 134);
53 text-align: left;
54 font-size: 13px;
55 line-height: 17px;
56 margin-top: 12px;
57}
58#card-element {
59 border-radius: 4px 4px 0 0 ;
60 padding: 12px;
61 border: 1px solid rgba(50, 50, 93, 0.1);
62 height: 44px;
63 width: 100%;
64 background: white;
65}
66#payment-request-button {
67 margin-bottom: 32px;
68}
69/* Buttons and links */
70button {
71 background: #5469d4;
72 color: #ffffff;
73 font-family: Arial, sans-serif;
74 border-radius: 0 0 4px 4px;
75 border: 0;
76 padding: 12px 16px;
77 font-size: 16px;
78 font-weight: 600;
79 cursor: pointer;
80 display: block;
81 transition: all 0.2s ease;
82 box-shadow: 0px 4px 5.5px 0px rgba(0, 0, 0, 0.07);
83 width: 100%;
84}
85button:hover {
86 filter: contrast(115%);
87}
88button:disabled {
89 opacity: 0.5;
90 cursor: default;
91}
92/* spinner/processing state, errors */
93.spinner,
94.spinner:before,
95.spinner:after {
96 border-radius: 50%;
97}
98.spinner {
99 color: #ffffff;
100 font-size: 22px;
101 text-indent: -99999px;
102 margin: 0px auto;
103 position: relative;
104 width: 20px;
105 height: 20px;
106 box-shadow: inset 0 0 0 2px;
107 -webkit-transform: translateZ(0);
108 -ms-transform: translateZ(0);
109 transform: translateZ(0);
110}
111.spinner:before,
112.spinner:after {
113 position: absolute;
114 content: "";
115}
116.spinner:before {
117 width: 10.4px;
118 height: 20.4px;
119 background: #5469d4;
120 border-radius: 20.4px 0 0 20.4px;
121 top: -0.2px;
122 left: -0.2px;
123 -webkit-transform-origin: 10.4px 10.2px;
124 transform-origin: 10.4px 10.2px;
125 -webkit-animation: loading 2s infinite ease 1.5s;
126 animation: loading 2s infinite ease 1.5s;
127}
128.spinner:after {
129 width: 10.4px;
130 height: 10.2px;
131 background: #5469d4;
132 border-radius: 0 10.2px 10.2px 0;
133 top: -0.1px;
134 left: 10.2px;
135 -webkit-transform-origin: 0px 10.2px;
136 transform-origin: 0px 10.2px;
137 -webkit-animation: loading 2s infinite ease;
138 animation: loading 2s infinite ease;
139}
140@-webkit-keyframes loading {
141 0% {
142 -webkit-transform: rotate(0deg);
143 transform: rotate(0deg);
144 }
145 100% {
146 -webkit-transform: rotate(360deg);
147 transform: rotate(360deg);
148 }
149}
150@keyframes loading {
151 0% {
152 -webkit-transform: rotate(0deg);
153 transform: rotate(0deg);
154 }
155 100% {
156 -webkit-transform: rotate(360deg);
157 transform: rotate(360deg);
158 }
159}
160@media only screen and (max-width: 600px) {
161 form {
162 width: 80vw;
163 }
164}
165 </style>
166</head>
167<body>
168<form id="payment-form">
169 <div id="card-element">
170 <!-- Elements will create input elements here -->
171 </div>
172
173 <!-- We'll put the error messages in this element -->
174 <div id="card-errors" role="alert"></div>
175
176 <button id="submit">SAVE PAYMENT METHOD</button>
177</form>
178<script>
179 var stripe = Stripe('pk_test_51GpsANHBs9CULvclYKA41mma52hk2wHJF8tKn96L524QXoE3KsY9qTDphxFLYN0PJ1OWkYHPswMyQnUekTdjFN4P00NN5W8AY0');
180var elements = stripe.elements();
181 var style = {
182 base: {
183 color: "#32325d",
184 }
185};
186
187var card = elements.create("card", { style: style });
188card.mount("#card-element");
189
190var form = document.getElementById('payment-form');
191
192form.addEventListener('submit', function(ev) {
193 ev.preventDefault();
194 stripe.confirmCardPayment(clientSecret, {
195 payment_method: {
196 card: card,
197 billing_details: {
198 name: 'Jenny Rosen'
199 }
200 }
201 }).then(function(result) {
202 if (result.error) {
203 // Show error to your customer (e.g., insufficient funds)
204 console.log(result.error.message);
205 } else {
206 // The payment has been processed!
207 if (result.paymentIntent.status === 'succeeded') {
208 // Show a success message to your customer
209 // There's a risk of the customer closing the window before callback
210 // execution. Set up a webhook or plugin to listen for the
211 // payment_intent.succeeded event that handles any business critical
212 // post-payment actions.
213 }
214 }
215 });
216});
217
218
219
220var response = fetch('/secret').then(function(response) {
221 return response.json();
222}).then(function(responseJson) {
223 var clientSecret = responseJson.client_secret;
224 // Call stripe.confirmCardPayment() with the client secret.
225});
226
227
228const express = require("express");
229const app = express();
230const { resolve } = require("path");
231// This is your real test secret API key.
232const stripe = require("stripe")(process.env.STRIPE_KEY);
233app.use(express.static("."));
234app.use(express.json());
235const calculateOrderAmount = items => {
236 // Replace this constant with a calculation of the order's amount
237 // Calculate the order total on the server to prevent
238 // people from directly manipulating the amount on the client
239 return 1400;
240};
241const chargeCustomer = async (customerId) => {
242 // Lookup the payment methods available for the customer
243 const paymentMethods = await stripe.paymentMethods.list({
244 customer: customerId,
245 type: "card"
246 });
247 // Charge the customer and payment method immediately
248 const paymentIntent = await stripe.paymentIntents.create({
249 amount: 1099,
250 currency: "usd",
251 customer: customerId,
252 payment_method: paymentMethods.data[0].id,
253 off_session: true,
254 confirm: true
255 });
256 if (paymentIntent.status === "succeeded") {
257 console.log("✅ Successfully charged card off session");
258 }
259}
260app.post("/create-payment-intent", async (req, res) => {
261 const { items } = req.body;
262 // Alternatively, set up a webhook to listen for the payment_intent.succeeded event
263 // and attach the PaymentMethod to a new Customer
264 const customer = await stripe.customers.create();
265 // Create a PaymentIntent with the order amount and currency
266 const paymentIntent = await stripe.paymentIntents.create({
267 customer: customer.id,
268 setup_future_usage: 'off_session',
269 amount: calculateOrderAmount(items),
270 currency: "usd"
271 });
272 res.send({
273 clientSecret: paymentIntent.client_secret
274 });
275});
276app.listen(4242, () => console.log('Node server listening on port 4242!'));
277
278
279</script>
280</body>
281</html>