class Element {
  mount(el) {
    if (typeof el === "string") {
      el = document.querySelector(el);
    }

    el.innerHTML = `
      <input id="stripe-cardnumber" placeholder="cardnumber" size="16" type="text">
      <input placeholder="exp-date" size="6" type="text">
      <input placeholder="cvc" size="3" type="text">
    `;
  }
}

window.Stripe = () => {
  const fetchLastFour = () => {
    return document.getElementById("stripe-cardnumber").value.substr(-4, 4);
  };

  return {
    elements: () => {
      return {
        create: (type, options) => new Element()
      };
    },

    createToken: card => {
      return new Promise(resolve => {
        resolve({ token: { id: "tok_123", card: { last4: fetchLastFour() } } });
      });
    }
  };
};

class Element {
  mount(el) {
    if (typeof el === "string") {
      el = document.querySelector(el);
    }

    el.innerHTML = `
      <input id="stripe-cardnumber" name="cardnumber" placeholder="Card number" size="16" type="text">
      <input name="exp-date" placeholder="MM / YY" size="6" type="text">
      <input name="cvc" placeholder="CVC" size="3" type="text">
    `;
  }
}

window.Stripe = () => {
  const fetchLastFour = () => {
    return document.getElementById("stripe-cardnumber").value.substr(-4, 4);
  };

  return {
    elements: () => {
      return {
        create: (type, options) => new Element()
      };
    },

    createToken: card => {
      return new Promise(resolve => {
        resolve({ token: { id: "tok_123", card: { last4: fetchLastFour() } } });
      });
    }
  };
};

Update form elements to more accurately reflect actual Stripe form
Update form elements to more accurately reflect actual Stripe form

These attributes more closely reflect the actual form injected by Stripe. The additional attributes are also useful for selecting elements in tests
