I tried to integration
Stripe (
Payment Checkout solution ) into my application in vain, the problem is that most Checkout solution as Form based with input fields and integrate fine with vaadin such as
PayPal (I use a
FormSender or
CustomLayout even though I could not find for the latter to add input field dynamically in the form html even with the “location”).
Anyway my point is below the form with Javascript from Stripe, this looks dangerous to me to execute the JS with the form where some code is added dynamically to the DOM (Button “Pay with Card” and token for the payment), and I understood
Vaadin is pretty safe removing potential dangerous JS from my component:
So I wrote a
Javascript Component from
Vaadin example and managed to get the form html loaded within a
Window or
CustomLayout , but the JS component does not display (Button “Pay with Card”) and the JS from stripe does not seems to be executed. I added all anotation & inspected the page everything seems fine , but it does not work !
Any idea or help on that matter would be great, I guess the onStateChange does only retrieve btw client & server the xhtml injected above and probably the associated DOM does not execute the script inside the form…
If you use innerHTML the script tag would not be evalutated.
Yuo can create form and script elements using javascript APIs in your connector script and then add them to the javascript component element (this.getElement()).
By the way you can also use shared state to store values for attributes of script tag (data-key, data-amount, data-image, …)
public class CheckoutJsLabelState extends JavaScriptComponentState {
public String key;
public String amount; // or a Number tye
...
}
Javascript component sets/gets values from shared state
@JavaScript(value = { "vaadin://themes/mytheme/js/checkout_stripe.js" })
public class CheckoutJs extends AbstractJavaScriptComponent {
public void setAmount(String amount) {
getState().amount = amount;
}
// .... other getter/setter
}
javascript connector creates dom elements; when shared state changes script tag will be removed and created again
window.com_innotek_ui_CheckoutJs = function() {
var me = this;
me.formElement = document.createElement("form");
me.formElement.setAttribute("action", "");
// ... set other form attributes
// add form to javascript component element
me.getElement().appendChild(me.formElement);
// create a new script tag with attributes from state
var makeScriptTag = function(state) {
var scriptEl = document.createElement("script");
scriptEl.setAttribute("src", "https://checkout.stripe.com/checkout.js")
scriptEl.setAttribute("data-key", state.key);
scriptEl.setAttribute("data-amount", state.amount);
scriptEl.setAttribute("data-currency", "eur");
// ... other script tag attributes
// with values hardcoded or from state
return scriptEl;
}
me.onStateChange = function() {
// remove existing script
var child = me.formElement.firstChild;
if (child) {
me.formElement.removeChild(child);
}
// add script tag as form child
me.formElement.appendChild(makeScriptTag(me.getState()));
}
}
Thank you Marco for this example from which you create all the form on the client side and setter / getter on the component side, I will give it a try and let you know if it works on my side.
Unfortunately the widget tag is empty, the only time I managed to get the form html of stripe was with the innerHTML but it was not evaluated as you mentionned. This script within a form from checkout stripe is really awkweird and dangerous to me but I am trying aside from PayPal to get Card payment solution for my startup…
Yep a security issue :
Content Security Policy: La directive « frame-src » est obsolète. Veuillez utiliser la directive « child-src » à la place. => unknown source !
AJS error or warning:
L’encodage de caractères d’un document en texte brut n’a pas été déclaré. Le document sera affiché avec des caractères incorrects pour certaines configurations de navigateur si le document contient des caractères en dehors de la plage US-ASCII. L’encodage de caractères du fichier doit être déclaré dans le protocole de transfert ou le fichier doit utiliser une marque d’ordre des octets (BOM) comme signature d’encodage. => checkout.js
Means encoding is not UTF8 but I do not have special characters… weird, seems more like a warning to me.
From chrome console, maybe this warning is a hint on the way the form html is badly inserted:
Resource interpreted as Document but transferred with MIME type application/x-javascript: “https://checkout.stripe.com/checkout.js”.