Buduję prostą stronę internetową, która będzie przetwarzać płatności za pomocą Stripe. Używam Bootstrap do stylizacji. Kiedy używam elementów pasków do wstawiania pól płatności, nie są one oznaczone stylem Bootstrap. Jak mogę zastosować stylizację Bootstrap do pól płatności Elementów?Jak mogę wyposażyć wejście Stripe Elements w Bootstrap?
Odpowiedz
Po wykopaniu około docs nieco więcej, uważam, że https://stripe.com/docs/stripe.js#the-element-container mówi „Ty powinny styl pojemnik Państwo zamontować elementem, jak gdyby był to na swojej stronie.”
Dodając form-control
klasy Bootstrap do tej <div>
ja Montaż elementów w pole wygląda prawie jak w każdym innym polu tekstowym Bootstrap stylu:
<div id="card-element" class="form-control"></div>
Z jakiegoś powodu, wysokość robi polowych „t dość mecz, ale metodą prób i błędów, mam go z:
var stripe = Stripe('your_key');
var elements = stripe.elements();
var card = elements.create('card', { style:
{
base: {
lineHeight: '1.429'
}
}
});
card.mount('#card-element');
porządku, więc musiałem dowiedzieć się tego, bo byłem za pomocą Stripe.js v2, a luka w zabezpieczeniach zostało wyjaśnione dzięki technice Stripe, więc czułem się zobowiązany do przejścia na Stripe.js v3 "Elements". Powiedzieli, że każdy javascript na tej samej stronie, co elementy karty kredytowej, może uzyskać wartości wrażliwych danych z karty kredytowej. Przypuszczam, że mogło się to zdarzyć, gdyby ktoś wciągał zewnętrzne skrypty ... i przypuszczam, że to musiało się stać, bo inaczej by się tym nie przejmowały. W każdym razie, w ten sposób otrzymałem elementy Stripe.js v3 pracujące z grupami wejściowymi Bootstrap 4. Jest to przykład działający, wystarczy, że zmienisz klucz publiczny.
Domyślnie jQuery przykład oparty
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>Stripe.js v3 with Bootstrap 4 Test</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
<style>
/* Blue outline on focus */
.StripeElement--focus {
border-color: #80BDFF;
outline:0;
box-shadow: 0 0 0 .2rem rgba(0,123,255,.25);
transition: border-color .15s ease-in-out, box-shadow .15s ease-in-out;
}
/* Can't see what I type without this */
#card-number.form-control,
#card-cvc.form-control,
#card-exp.form-control {
display:inline-block;
}
</style>
</head>
<body>
<div class="container-fluid">
<h1 class="mt-5">Stripe.js v3 with Bootstrap 4 (beta) Test</h1>
<div id="card-errors" role="alert"></div>
<div class="card">
<div class="card-body">
<form id="payment-form">
<label for="name">Name on Card</label>
<div class="input-group mb-2">
<div class="input-group-prepend">
<span class="input-group-text">A</span>
</div>
<input type="text" class="form-control" id="name">
<div class="input-group-append">
<span class="input-group-text">B</span>
</div>
</div>
<label for="card-number">Credit Card Number</label>
<div class="input-group mb-2">
<div class="input-group-prepend">
<span class="input-group-text">C</span>
</div>
<span id="card-number" class="form-control">
<!-- Stripe Card Element -->
</span>
<div class="input-group-append">
<span class="input-group-text">D</span>
</div>
</div>
<label for="card-cvc">CVC Number</label>
<div class="input-group mb-2">
<div class="input-group-prepend">
<span class="input-group-text">E</span>
</div>
<span id="card-cvc" class="form-control">
<!-- Stripe CVC Element -->
</span>
</div>
<label for="card-exp">Expiration</label>
<div class="input-group mb-2">
<span id="card-exp" class="form-control">
<!-- Stripe Card Expiry Element -->
</span>
<div class="input-group-append">
<span class="input-group-text">F</span>
</div>
</div>
<button id="payment-submit" class="btn btn-primary mt-1">Submit Payment</button>
</form>
</div>
</div>
</div>
<script src="https://code.jquery.com/jquery-3.2.1.min.js" integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4=" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script>
<script src="https://js.stripe.com/v3/"></script>
<script>
$(document).ready(function(){
// Create a Stripe client
var stripe = Stripe('pk_test_XxXxXxXxXxXxXxXxXxXxXxXx');
// Create an instance of Elements
var elements = stripe.elements();
// Try to match bootstrap 4 styling
var style = {
base: {
'lineHeight': '1.35',
'fontSize': '1.11rem',
'color': '#495057',
'fontFamily': 'apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif'
}
};
// Card number
var card = elements.create('cardNumber', {
'placeholder': '',
'style': style
});
card.mount('#card-number');
// CVC
var cvc = elements.create('cardCvc', {
'placeholder': '',
'style': style
});
cvc.mount('#card-cvc');
// Card expiry
var exp = elements.create('cardExpiry', {
'placeholder': '',
'style': style
});
exp.mount('#card-exp');
// Submit
$('#payment-submit').on('click', function(e){
e.preventDefault();
var cardData = {
'name': $('#name').val()
};
stripe.createToken(card, cardData).then(function(result) {
console.log(result);
if(result.error && result.error.message){
alert(result.error.message);
}else{
alert(result.token.id);
}
});
});
});
</script>
</body>
</html>
testowałem tylko w Firefox, Chrome i Chrome na Androida. Wydaje się działać dobrze. Daj mi znać, jeśli wystąpią jakiekolwiek problemy.
Opcjonalnie Vue.js Based Przykład
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>Stripe.js v3 with Bootstrap 4 and Vue.js</title>
<link type="text/css" rel="stylesheet" href="https://unpkg.com/bootstrap/dist/css/bootstrap.min.css"/>
<link type="text/css" rel="stylesheet" href="https://unpkg.com/[email protected]/dist/bootstrap-vue.css"/>
<style>
/* This background color not essential for the example */
html, body {
background:#999;
}
/* Padding for Stripe Element containers */
.stripe-element-container {
padding-top: .55rem;
padding-bottom: .50rem;
}
/* Blue outline on focus */
.StripeElement--focus {
border-color: #80BDFF;
outline:0;
box-shadow: 0 0 0 .2rem rgba(0,123,255,.25);
transition: border-color .15s ease-in-out, box-shadow .15s ease-in-out;
}
/* Can't see what I type without this */
#card-number.form-control,
#card-cvc.form-control,
#card-exp.form-control {
display:inline-block;
}
</style>
</head>
<body>
<div id="app">
<stripe-form inline-template>
<div class="container-fluid">
<div class="row">
<div class="col-md-4 offset-md-4 pt-5">
<div class="card">
<div class="card-header">
<h3 class="mb-0">Pay Now</h3>
</div>
<div class="card-body">
<div v-bind:class="{alert: activeError, 'alert-danger': activeError}" role="alert" v-html="errorText"></div>
<form>
<div class="form-group mb-4">
<label for="name">Name on Card</label>
<input type="text" class="form-control" v-model="ccName" />
</div>
<div class="form-group">
<label for="card-number">Credit Card Number</label>
<span id="card-number" class="form-control stripe-element-container">
<!-- Stripe Card Element -->
</span>
</div>
<div class="form-group">
<label for="card-cvc">CVC Number</label>
<span id="card-cvc" class="form-control stripe-element-container">
<!-- Stripe CVC Element -->
</span>
</div>
<div class="form-group">
<label for="card-exp">Expiration</label>
<span id="card-exp" class="form-control stripe-element-container">
<!-- Stripe Card Expiry Element -->
</span>
</div>
<button @click.prevent="paymentSubmit" class="btn btn-primary mt-1 float-right">Submit Payment</button>
</form>
</div>
</div>
</div>
</div>
</div>
</stripe-form>
<modal></modal>
</div>
<script src="https://unpkg.com/[email protected]/dist/vue.js"></script>
<script src="https://unpkg.com/[email protected]/dist/polyfill.min.js"></script>
<script src="https://unpkg.com/[email protected]/dist/bootstrap-vue.js"></script>
<script src="https://js.stripe.com/v3/"></script>
<script>
// Your Stripe public key
const stripePublicKey = 'pk_test_XxXxXxXxXxXxXxXxXxXxXxXx';
/**
* Class allows firing of events and
* listening of events between components
*/
window.Events = new class {
constructor(){
this.vue = new Vue();
}
fire(event, data = null){
this.vue.$emit(event, data);
}
listenFor(event, callback){
this.vue.$on(event, callback);
}
}
/**
* See: https://bootstrap-vue.js.org/docs/components/modal/
*/
Vue.component('modal', {
template: `
<div>
<b-modal ref="myModalRef" ok-only ok-title="Close" v-bind:title="title">
<p class="mb-0">{{ body }}</p>
</b-modal>
</div>
`,
data: function(){
return {
title: '',
body: ''
}
},
methods: {
showModal() {
this.$refs.myModalRef.show()
}
/* This not needed for this example
,
hideModal() {
this.$refs.myModalRef.hide()
}
*/
},
created(){
Events.listenFor('modalShow', (data) => {
this.title = data.title;
this.body = data.message;
this.showModal();
});
}
});
Vue.component('stripe-form', {
data: function(){
return {
activeError: false,
errorText: '',
ccName: '',
stripe: null,
card: null,
cvc: null,
exp: null
}
},
methods: {
paymentSubmit: function(){
let cardData = {
'name': this.ccName
};
// Ensure the name field is not empty
if(cardData.name.trim() == ''){
// Show an error
this.activeError = true;
this.errorText = '<b>Submission Error:</b><br />Name is required.';
// Abort !!
return;
}
this.stripe.createToken(this.card, cardData).then((result) => {
if(result.error && result.error.message){
// Show any errors
this.activeError = true;
this.errorText = '<b>Submission Error:</b><br />' + result.error.message;
}else{
/**
* Success message in modal.
* This is normally where you'd post to your server,
* and have it actually attempt the credit card transaction
* using the token ID that was just received.
*/
Events.fire('modalShow', {
'title': 'Success',
'message': result.token.id
});
// Clear the form
this.activeError = false;
this.errorText = '';
this.ccName = '';
// Stripe elements must be cleared in a special way
this.card.clear();
this.cvc.clear();
this.exp.clear();
}
});
}
},
mounted: function(){
// Create a Stripe client
this.stripe = Stripe(stripePublicKey);
// Create an instance of Elements
const elements = this.stripe.elements();
/**
* Try to match bootstrap 4 styling.
* --------------------------------
* fontSize was in rem units, but Stripe says that it should be in pixels.
*/
const style = {
base: {
'fontSize': '16px',
'color': '#495057',
'fontFamily': 'apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif'
}
};
// Card number
this.card = elements.create('cardNumber', {
'placeholder': '',
'style': style
});
this.card.mount('#card-number');
// CVC
this.cvc = elements.create('cardCvc', {
'placeholder': '',
'style': style
});
this.cvc.mount('#card-cvc');
// Card expiry
this.exp = elements.create('cardExpiry', {
'placeholder': '',
'style': style
});
this.exp.mount('#card-exp');
}
});
new Vue({ el: '#app' });
</script>
</body>
</html>
Ten Vue.js Przykładem może korzystać z niektórych prac, ale może pomóc Ci zacząć.
To wygląda świetnie dla mnie! Zdecydowanie złapałeś kilka stylów, które przegapiłem. – michael
To prawda, ale należy również zastosować kolor obramowania, gdy element jest skupiony. Ponadto, jeśli używasz Bootstrap 4 beta i próbujesz użyć grup wejściowych, musisz zmienić CSS elementu tak, aby był to 'display: block' zamiast' display: flex'. Mam działające demo tego ... ale tak naprawdę nie jest to odpowiedź na twoje pytanie ... chyba że tak jest. –
Świetne punkty! To brzmi jak odpowiedź :) Chciałbym zobaczyć demo. – michael