2017-09-04 67 views
10

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

6

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'); 
+0

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. –

+0

Świetne punkty! To brzmi jak odpowiedź :) Chciałbym zobaczyć demo. – michael

10

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ąć.

+0

To wygląda świetnie dla mnie! Zdecydowanie złapałeś kilka stylów, które przegapiłem. – michael